diff options
Diffstat (limited to 'libc/include')
-rw-r--r-- | libc/include/android/fdsan.h | 4 | ||||
-rw-r--r-- | libc/include/android/legacy_signal_inlines.h | 2 | ||||
-rw-r--r-- | libc/include/arpa/nameser.h | 50 | ||||
-rw-r--r-- | libc/include/bits/elf_arm64.h | 6 | ||||
-rw-r--r-- | libc/include/bits/fortify/fcntl.h | 46 | ||||
-rw-r--r-- | libc/include/bits/fortify/stdio.h | 15 | ||||
-rw-r--r-- | libc/include/bits/fortify/stdlib.h | 5 | ||||
-rw-r--r-- | libc/include/bits/fortify/string.h | 44 | ||||
-rw-r--r-- | libc/include/bits/fortify/strings.h | 59 | ||||
-rw-r--r-- | libc/include/bits/fortify/unistd.h | 3 | ||||
-rw-r--r-- | libc/include/bits/glibc-syscalls.h | 18 | ||||
-rw-r--r-- | libc/include/bits/stdatomic.h | 286 | ||||
-rw-r--r-- | libc/include/bits/timespec.h | 2 | ||||
-rw-r--r-- | libc/include/pthread.h | 20 | ||||
-rw-r--r-- | libc/include/semaphore.h | 8 | ||||
-rw-r--r-- | libc/include/stdatomic.h | 258 | ||||
-rw-r--r-- | libc/include/stdio.h | 44 | ||||
-rw-r--r-- | libc/include/stdlib.h | 2 | ||||
-rw-r--r-- | libc/include/strings.h | 20 | ||||
-rw-r--r-- | libc/include/sys/cdefs.h | 3 | ||||
-rw-r--r-- | libc/include/sys/mman.h | 146 |
21 files changed, 699 insertions, 342 deletions
diff --git a/libc/include/android/fdsan.h b/libc/include/android/fdsan.h index 1169ed046..83b9318ba 100644 --- a/libc/include/android/fdsan.h +++ b/libc/include/android/fdsan.h @@ -197,4 +197,8 @@ enum android_fdsan_error_level android_fdsan_get_error_level() __INTRODUCED_IN(2 */ enum android_fdsan_error_level android_fdsan_set_error_level(enum android_fdsan_error_level new_level) __INTRODUCED_IN(29) __attribute__((__weak__)); +/* + * Set the error level to the global setting if available, or a default value. + */ +enum android_fdsan_error_level android_fdsan_set_error_level_from_property(enum android_fdsan_error_level default_level) __INTRODUCED_IN(30) __attribute__((__weak__)); __END_DECLS diff --git a/libc/include/android/legacy_signal_inlines.h b/libc/include/android/legacy_signal_inlines.h index 5ca9813f3..d2c767703 100644 --- a/libc/include/android/legacy_signal_inlines.h +++ b/libc/include/android/legacy_signal_inlines.h @@ -52,7 +52,7 @@ static __inline int __ndk_legacy___libc_current_sigrtmax() { static __inline int __ndk_legacy___libc_current_sigrtmin() { if (__libc_current_sigrtmin) return __libc_current_sigrtmin(); - return __SIGRTMIN + 6; /* Should match __libc_current_sigrtmin. */ + return __SIGRTMIN + 7; /* Should match __libc_current_sigrtmin. */ } #undef SIGRTMAX diff --git a/libc/include/arpa/nameser.h b/libc/include/arpa/nameser.h index e0b5c4514..89ece1c5e 100644 --- a/libc/include/arpa/nameser.h +++ b/libc/include/arpa/nameser.h @@ -591,33 +591,29 @@ int ns_samename(const char* __lhs, const char* __rhs); /* The names of these symbols were accidentally prefixed with __ in L. */ /* The duplication here is intentional to avoid declaring different symbols with the same * declaration. */ -int ns_msg_getflag(ns_msg __handle, int __flag) __INTRODUCED_IN_64(23); -uint16_t ns_get16(const u_char* __src) __INTRODUCED_IN_64(23); -uint32_t ns_get32(const u_char* __src) __INTRODUCED_IN_64(23); -void ns_put16(uint16_t __src, u_char* __dst) __INTRODUCED_IN_64(23); -void ns_put32(uint32_t __src, u_char* __dst) __INTRODUCED_IN_64(23); -int ns_initparse(const u_char* __msg, int __msg_size, ns_msg* __handle) __INTRODUCED_IN_64(23); -int ns_skiprr(const u_char* __ptr, const u_char* __eom, ns_sect __section, int __count) __INTRODUCED_IN_64(23); -int ns_parserr(ns_msg* __handle, ns_sect __section, int __rr_number, ns_rr* __rr) __INTRODUCED_IN_64(23); -int ns_sprintrr(const ns_msg* __handle, const ns_rr* __rr, const char* __name_ctx, const char* __origin, char* __buf, size_t __buf_size) - __INTRODUCED_IN_64(23); -int ns_sprintrrf(const u_char* __msg, size_t __msg_size, const char* __name, ns_class __class, ns_type __type, u_long __ttl, const u_char* __rdata, size_t __rdata_size, const char* __name_ctx, const char* __origin, char* __buf, size_t __buf_size) __INTRODUCED_IN_64(23); -int ns_format_ttl(u_long __ttl, char* __dst, size_t __dst_size) __INTRODUCED_IN_64(23); -int ns_name_ntol(const u_char* __src, u_char* __dst, size_t __dst_size) __INTRODUCED_IN_64(23); -int ns_name_ntop(const u_char* __src, char* __dst, size_t __dst_size) __INTRODUCED_IN_64(23); -int ns_name_pton(const char* __src, u_char* __dst, size_t __dst_size) __INTRODUCED_IN_64(23); -int ns_name_unpack(const u_char* __msg, const u_char* __eom, const u_char* __src, u_char* __dst, size_t __dst_size) - __INTRODUCED_IN_64(23); -int ns_name_pack(const u_char* __src, u_char* __dst, int __dst_size, const u_char** __dn_ptrs, const u_char** __last_dn_ptr) __INTRODUCED_IN_64(23); -int ns_name_uncompress(const u_char* __msg, const u_char* __eom, const u_char* __src, char* __dst, size_t __dst_size) - __INTRODUCED_IN_64(23); -int ns_name_compress(const char* __src, u_char* __dst, size_t __dst_size, const u_char** __dn_ptrs, const u_char** __last_dn_ptr) - __INTRODUCED_IN_64(23); -int ns_name_skip(const u_char** __ptr_ptr, const u_char* __eom) __INTRODUCED_IN_64(23); -void ns_name_rollback(const u_char* __src, const u_char** __dn_ptrs, const u_char** __last_dn_ptr) __INTRODUCED_IN_64(23); - -int ns_makecanon(const char* __src, char* __dst, size_t __dst_size) __INTRODUCED_IN_64(23); -int ns_samename(const char* __lhs, const char* __rhs) __INTRODUCED_IN_64(23); +int ns_msg_getflag(ns_msg __handle, int __flag) __INTRODUCED_IN_64(22); +uint16_t ns_get16(const u_char* __src) __INTRODUCED_IN_64(22); +uint32_t ns_get32(const u_char* __src) __INTRODUCED_IN_64(22); +void ns_put16(uint16_t __src, u_char* __dst) __INTRODUCED_IN_64(22); +void ns_put32(uint32_t __src, u_char* __dst) __INTRODUCED_IN_64(22); +int ns_initparse(const u_char* __msg, int __msg_size, ns_msg* __handle) __INTRODUCED_IN_64(22); +int ns_skiprr(const u_char* __ptr, const u_char* __eom, ns_sect __section, int __count) __INTRODUCED_IN_64(22); +int ns_parserr(ns_msg* __handle, ns_sect __section, int __rr_number, ns_rr* __rr) __INTRODUCED_IN_64(22); +int ns_sprintrr(const ns_msg* __handle, const ns_rr* __rr, const char* __name_ctx, const char* __origin, char* __buf, size_t __buf_size) __INTRODUCED_IN_64(22); +int ns_sprintrrf(const u_char* __msg, size_t __msg_size, const char* __name, ns_class __class, ns_type __type, u_long __ttl, const u_char* __rdata, size_t __rdata_size, const char* __name_ctx, const char* __origin, char* __buf, size_t __buf_size) __INTRODUCED_IN_64(22); +int ns_format_ttl(u_long __ttl, char* __dst, size_t __dst_size) __INTRODUCED_IN_64(22); +int ns_name_ntol(const u_char* __src, u_char* __dst, size_t __dst_size) __INTRODUCED_IN_64(22); +int ns_name_ntop(const u_char* __src, char* __dst, size_t __dst_size) __INTRODUCED_IN_64(22); +int ns_name_pton(const char* __src, u_char* __dst, size_t __dst_size) __INTRODUCED_IN_64(22); +int ns_name_unpack(const u_char* __msg, const u_char* __eom, const u_char* __src, u_char* __dst, size_t __dst_size) __INTRODUCED_IN_64(22); +int ns_name_pack(const u_char* __src, u_char* __dst, int __dst_size, const u_char** __dn_ptrs, const u_char** __last_dn_ptr) __INTRODUCED_IN_64(22); +int ns_name_uncompress(const u_char* __msg, const u_char* __eom, const u_char* __src, char* __dst, size_t __dst_size) __INTRODUCED_IN_64(22); +int ns_name_compress(const char* __src, u_char* __dst, size_t __dst_size, const u_char** __dn_ptrs, const u_char** __last_dn_ptr) __INTRODUCED_IN_64(22); +int ns_name_skip(const u_char** __ptr_ptr, const u_char* __eom) __INTRODUCED_IN_64(22); +void ns_name_rollback(const u_char* __src, const u_char** __dn_ptrs, const u_char** __last_dn_ptr) __INTRODUCED_IN_64(22); + +int ns_makecanon(const char* __src, char* __dst, size_t __dst_size) __INTRODUCED_IN_64(22); +int ns_samename(const char* __lhs, const char* __rhs) __INTRODUCED_IN_64(22); #endif /* !defined(__LP64__) */ __END_DECLS diff --git a/libc/include/bits/elf_arm64.h b/libc/include/bits/elf_arm64.h index d838c0b2d..6bb8384e4 100644 --- a/libc/include/bits/elf_arm64.h +++ b/libc/include/bits/elf_arm64.h @@ -83,9 +83,9 @@ #define R_AARCH64_GLOB_DAT 1025 /* Create GOT entry. */ #define R_AARCH64_JUMP_SLOT 1026 /* Create PLT entry. */ #define R_AARCH64_RELATIVE 1027 /* Adjust by program base. */ -#define R_AARCH64_TLS_DTPREL64 1028 /* Module-relative offset. */ -#define R_AARCH64_TLS_DTPMOD64 1029 /* Module index. */ -#define R_AARCH64_TLS_TPREL64 1030 /* TP-relative offset. */ +#define R_AARCH64_TLS_DTPMOD 1028 /* Module index. */ +#define R_AARCH64_TLS_DTPREL 1029 /* Module-relative offset. */ +#define R_AARCH64_TLS_TPREL 1030 /* TP-relative offset. */ #define R_AARCH64_TLSDESC 1031 /* 16-byte descriptor: resolver func + arg. */ #define R_AARCH64_IRELATIVE 1032 diff --git a/libc/include/bits/fortify/fcntl.h b/libc/include/bits/fortify/fcntl.h index e7f2c8263..4bb441eee 100644 --- a/libc/include/bits/fortify/fcntl.h +++ b/libc/include/bits/fortify/fcntl.h @@ -92,6 +92,52 @@ int openat(int dirfd, const char* const __pass_object_size pathname, int flags, } #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */ +#if __ANDROID_API__ >= __ANDROID_API_R__ +int __open64_2(const char*, int) __INTRODUCED_IN(30); +int __openat64_2(int, const char*, int) __INTRODUCED_IN(30); +int __open64_real(const char* __path, int __flags, ...) __RENAME(open64); +int __openat64_real(int, const char*, int, ...) __RENAME(openat64); + +__BIONIC_ERROR_FUNCTION_VISIBILITY +int open64(const char* pathname, int flags, mode_t modes, ...) __overloadable + __errorattr(__open_too_many_args_error); + +__BIONIC_FORTIFY_INLINE +int open64(const char* const __pass_object_size pathname, int flags) + __overloadable + __clang_error_if(__open_modes_useful(flags), "'open64' " __open_too_few_args_error) { + return __open64_2(pathname, flags); +} + +__BIONIC_FORTIFY_INLINE +int open64(const char* const __pass_object_size pathname, int flags, mode_t modes) + __overloadable + __clang_warning_if(!__open_modes_useful(flags) && modes, + "'open64' " __open_useless_modes_warning) { + return __open64_real(pathname, flags, modes); +} + +__BIONIC_ERROR_FUNCTION_VISIBILITY +int openat64(int dirfd, const char* pathname, int flags, mode_t modes, ...) + __overloadable + __errorattr(__open_too_many_args_error); + +__BIONIC_FORTIFY_INLINE +int openat64(int dirfd, const char* const __pass_object_size pathname, int flags) + __overloadable + __clang_error_if(__open_modes_useful(flags), "'openat64' " __open_too_few_args_error) { + return __openat64_2(dirfd, pathname, flags); +} + +__BIONIC_FORTIFY_INLINE +int openat64(int dirfd, const char* const __pass_object_size pathname, int flags, mode_t modes) + __overloadable + __clang_warning_if(!__open_modes_useful(flags) && modes, + "'openat64' " __open_useless_modes_warning) { + return __openat64_real(dirfd, pathname, flags, modes); +} +#endif /* __ANDROID_API__ >= __ANDROID_API_R__ */ + #undef __open_too_many_args_error #undef __open_too_few_args_error #undef __open_useless_modes_warning diff --git a/libc/include/bits/fortify/stdio.h b/libc/include/bits/fortify/stdio.h index 6e47dafee..e766b2007 100644 --- a/libc/include/bits/fortify/stdio.h +++ b/libc/include/bits/fortify/stdio.h @@ -39,6 +39,8 @@ size_t __fwrite_chk(const void*, size_t, size_t, FILE*, size_t) __INTRODUCED_IN( #if __ANDROID_API__ >= __ANDROID_API_J_MR1__ __BIONIC_FORTIFY_INLINE __printflike(3, 0) int vsnprintf(char* const __pass_object_size dest, size_t size, const char* format, va_list ap) + __clang_error_if(__bos_unevaluated_lt(__bos(dest), size), + "in call to 'vsnprintf', size is larger than the destination buffer") __overloadable { return __builtin___vsnprintf_chk(dest, size, 0, __bos(dest), format, ap); } @@ -50,19 +52,10 @@ int vsprintf(char* const __pass_object_size dest, const char* format, va_list ap #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */ #if __ANDROID_API__ >= __ANDROID_API_J_MR1__ -/* - * Simple case: `format` can't have format specifiers, so we can just compare - * its length to the length of `dest` - */ -__BIONIC_ERROR_FUNCTION_VISIBILITY -int snprintf(char* dest, size_t size, const char* format) - __overloadable - __enable_if(__bos_unevaluated_lt(__bos(dest), __builtin_strlen(format)), - "format string will always overflow destination buffer") - __errorattr("format string will always overflow destination buffer"); - __BIONIC_FORTIFY_VARIADIC __printflike(3, 4) int snprintf(char* const __pass_object_size dest, size_t size, const char* format, ...) + __clang_error_if(__bos_unevaluated_lt(__bos(dest), size), + "in call to 'snprintf', size is larger than the destination buffer") __overloadable { va_list va; va_start(va, format); diff --git a/libc/include/bits/fortify/stdlib.h b/libc/include/bits/fortify/stdlib.h index 0bb3d0d66..623be583b 100644 --- a/libc/include/bits/fortify/stdlib.h +++ b/libc/include/bits/fortify/stdlib.h @@ -36,10 +36,11 @@ #define __PATH_MAX 4096 char* realpath(const char* path, char* resolved) + __clang_error_if(!path, "'realpath': NULL path is never correct; flipped arguments?") __clang_error_if(__bos_unevaluated_lt(__bos(resolved), __PATH_MAX), "'realpath' output parameter must be NULL or a pointer to a buffer " - "with >= PATH_MAX bytes") - __clang_error_if(!path, "'realpath': NULL path is never correct; flipped arguments?"); + "with >= PATH_MAX bytes"); + /* No need for a definition; the only issues we can catch are at compile-time. */ #undef __PATH_MAX diff --git a/libc/include/bits/fortify/string.h b/libc/include/bits/fortify/string.h index 1e129868c..70e4476b4 100644 --- a/libc/include/bits/fortify/string.h +++ b/libc/include/bits/fortify/string.h @@ -66,6 +66,22 @@ void* memmove(void* const dst __pass_object_size0, const void* src, size_t len) } #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */ +#if defined(__USE_GNU) +#if __ANDROID_API__ >= __ANDROID_API_R__ +__BIONIC_FORTIFY_INLINE +void* mempcpy(void* const dst __pass_object_size0, const void* src, size_t copy_amount) + __overloadable + __clang_error_if(__bos_unevaluated_lt(__bos0(dst), copy_amount), + "'mempcpy' called with size bigger than buffer") { + size_t bos_dst = __bos0(dst); + if (__bos_trivially_not_lt(bos_dst, copy_amount)) { + return __builtin_mempcpy(dst, src, copy_amount); + } + return __builtin___mempcpy_chk(dst, src, copy_amount, bos_dst); +} +#endif /* __ANDROID_API__ >= __ANDROID_API_R__ */ +#endif + #if __ANDROID_API__ >= __ANDROID_API_L__ __BIONIC_FORTIFY_INLINE char* stpcpy(char* const dst __pass_object_size, const char* src) @@ -94,12 +110,18 @@ char* strcpy(char* const dst __pass_object_size, const char* src) } __BIONIC_FORTIFY_INLINE -char* strcat(char* const dst __pass_object_size, const char* src) __overloadable { +char* strcat(char* const dst __pass_object_size, const char* src) + __overloadable + __clang_error_if(__bos_unevaluated_le(__bos(dst), __builtin_strlen(src)), + "'strcat' called with string bigger than buffer") { return __builtin___strcat_chk(dst, src, __bos(dst)); } __BIONIC_FORTIFY_INLINE -char* strncat(char* const dst __pass_object_size, const char* src, size_t n) __overloadable { +char* strncat(char* const dst __pass_object_size, const char* src, size_t n) + __overloadable + __clang_error_if(__bos_unevaluated_lt(__bos(dst), n), + "'strncat' called with size bigger than buffer") { return __builtin___strncat_chk(dst, src, n, __bos(dst)); } @@ -145,7 +167,9 @@ void* __memrchr_fortify(const void* const __pass_object_size s, int c, size_t n) #if __ANDROID_API__ >= __ANDROID_API_L__ __BIONIC_FORTIFY_INLINE char* stpncpy(char* const dst __pass_object_size, const char* const src __pass_object_size, size_t n) - __overloadable { + __overloadable + __clang_error_if(__bos_unevaluated_lt(__bos(dst), n), + "'stpncpy' called with size bigger than buffer") { size_t bos_dst = __bos(dst); size_t bos_src = __bos(src); @@ -159,7 +183,9 @@ char* stpncpy(char* const dst __pass_object_size, const char* const src __pass_o __BIONIC_FORTIFY_INLINE char* strncpy(char* const dst __pass_object_size, const char* const src __pass_object_size, size_t n) - __overloadable { + __overloadable + __clang_error_if(__bos_unevaluated_lt(__bos(dst), n), + "'strncpy' called with size bigger than buffer") { size_t bos_dst = __bos(dst); size_t bos_src = __bos(src); @@ -174,7 +200,10 @@ char* strncpy(char* const dst __pass_object_size, const char* const src __pass_o #if __ANDROID_API__ >= __ANDROID_API_J_MR1__ __BIONIC_FORTIFY_INLINE -size_t strlcpy(char* const dst __pass_object_size, const char* src, size_t size) __overloadable { +size_t strlcpy(char* const dst __pass_object_size, const char* src, size_t size) + __overloadable + __clang_error_if(__bos_unevaluated_lt(__bos(dst), size), + "'strlcpy' called with size bigger than buffer") { size_t bos = __bos(dst); if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { @@ -185,7 +214,10 @@ size_t strlcpy(char* const dst __pass_object_size, const char* src, size_t size) } __BIONIC_FORTIFY_INLINE -size_t strlcat(char* const dst __pass_object_size, const char* src, size_t size) __overloadable { +size_t strlcat(char* const dst __pass_object_size, const char* src, size_t size) + __overloadable + __clang_error_if(__bos_unevaluated_lt(__bos(dst), size), + "'strlcat' called with size bigger than buffer") { size_t bos = __bos(dst); if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { diff --git a/libc/include/bits/fortify/strings.h b/libc/include/bits/fortify/strings.h new file mode 100644 index 000000000..6bda295f3 --- /dev/null +++ b/libc/include/bits/fortify/strings.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(__BIONIC_FORTIFY) + +#if __ANDROID_API__ >= __ANDROID_API_J_MR1__ +__BIONIC_FORTIFY_INLINE +void bcopy(const void *src, void* const dst __pass_object_size0, size_t len) + __overloadable + __clang_error_if(__bos_unevaluated_lt(__bos0(dst), len), + "'bcopy' called with size bigger than buffer") { + size_t bos = __bos0(dst); + if (__bos_trivially_not_lt(bos, len)) { + __builtin_memmove(dst, src, len); + } else { + __builtin___memmove_chk(dst, src, len, bos); + } +} + +__BIONIC_FORTIFY_INLINE +void bzero(void* const b __pass_object_size0, size_t len) + __overloadable + __clang_error_if(__bos_unevaluated_lt(__bos0(b), len), + "'bzero' called with size bigger than buffer") { + size_t bos = __bos0(b); + if (__bos_trivially_not_lt(bos, len)) { + __builtin_memset(b, 0, len); + } else { + __builtin___memset_chk(b, 0, len, bos); + } +} +#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */ + +#endif /* defined(__BIONIC_FORTIFY) */ diff --git a/libc/include/bits/fortify/unistd.h b/libc/include/bits/fortify/unistd.h index 543c3c748..547a1686c 100644 --- a/libc/include/bits/fortify/unistd.h +++ b/libc/include/bits/fortify/unistd.h @@ -67,7 +67,8 @@ ssize_t __readlinkat_chk(int dirfd, const char*, char*, size_t, size_t) __INTROD "in call to '" #fn "', '" #what "' bytes overflows the given object") #define __bos_trivially_not_lt_no_overflow(bos_val, index) \ - __bos_dynamic_check_impl_and((bos_val), >=, (index), (bos_val) <= SSIZE_MAX) + ((__bos_dynamic_check_impl_and((bos_val), >=, (index), (bos_val) <= SSIZE_MAX) && \ + __builtin_constant_p(index) && (index) <= SSIZE_MAX)) #if __ANDROID_API__ >= __ANDROID_API_N__ __BIONIC_FORTIFY_INLINE diff --git a/libc/include/bits/glibc-syscalls.h b/libc/include/bits/glibc-syscalls.h index 6940b3e1c..6b3e347c2 100644 --- a/libc/include/bits/glibc-syscalls.h +++ b/libc/include/bits/glibc-syscalls.h @@ -243,9 +243,21 @@ #if defined(__NR_fremovexattr) #define SYS_fremovexattr __NR_fremovexattr #endif +#if defined(__NR_fsconfig) + #define SYS_fsconfig __NR_fsconfig +#endif #if defined(__NR_fsetxattr) #define SYS_fsetxattr __NR_fsetxattr #endif +#if defined(__NR_fsmount) + #define SYS_fsmount __NR_fsmount +#endif +#if defined(__NR_fsopen) + #define SYS_fsopen __NR_fsopen +#endif +#if defined(__NR_fspick) + #define SYS_fspick __NR_fspick +#endif #if defined(__NR_fstat) #define SYS_fstat __NR_fstat #endif @@ -582,6 +594,9 @@ #if defined(__NR_mount) #define SYS_mount __NR_mount #endif +#if defined(__NR_move_mount) + #define SYS_move_mount __NR_move_mount +#endif #if defined(__NR_move_pages) #define SYS_move_pages __NR_move_pages #endif @@ -678,6 +693,9 @@ #if defined(__NR_open_by_handle_at) #define SYS_open_by_handle_at __NR_open_by_handle_at #endif +#if defined(__NR_open_tree) + #define SYS_open_tree __NR_open_tree +#endif #if defined(__NR_openat) #define SYS_openat __NR_openat #endif diff --git a/libc/include/bits/stdatomic.h b/libc/include/bits/stdatomic.h new file mode 100644 index 000000000..633cb8665 --- /dev/null +++ b/libc/include/bits/stdatomic.h @@ -0,0 +1,286 @@ +/*- + * Copyright (c) 2011 Ed Schouten <ed@FreeBSD.org> + * David Chisnall <theraven@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#pragma once + +#include <sys/cdefs.h> +#include <sys/types.h> +#include <stdbool.h> + +/* + * C: Do it ourselves. + * Note that the runtime representation defined here should be compatible + * with the C++ one, i.e. an _Atomic(T) needs to contain the same + * bits as a T. + */ + +#include <stddef.h> /* For ptrdiff_t. */ +#include <stdint.h> /* TODO: don't drag in all the macros, just the types. */ +// Include uchar.h only when available. Bionic's stdatomic.h is also used for +// the host (via a copy in prebuilts/clang) and uchar.h is not available in the +// glibc used for the host. +#if defined(__BIONIC__) +# include <uchar.h> /* For char16_t and char32_t. */ +#endif + +/* + * 7.17.1 Atomic lock-free macros. + */ + +#ifdef __GCC_ATOMIC_BOOL_LOCK_FREE +#define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE +#endif +#ifdef __GCC_ATOMIC_CHAR_LOCK_FREE +#define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE +#endif +#ifdef __GCC_ATOMIC_CHAR16_T_LOCK_FREE +#define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE +#endif +#ifdef __GCC_ATOMIC_CHAR32_T_LOCK_FREE +#define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE +#endif +#ifdef __GCC_ATOMIC_WCHAR_T_LOCK_FREE +#define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE +#endif +#ifdef __GCC_ATOMIC_SHORT_LOCK_FREE +#define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE +#endif +#ifdef __GCC_ATOMIC_INT_LOCK_FREE +#define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE +#endif +#ifdef __GCC_ATOMIC_LONG_LOCK_FREE +#define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE +#endif +#ifdef __GCC_ATOMIC_LLONG_LOCK_FREE +#define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE +#endif +#ifdef __GCC_ATOMIC_POINTER_LOCK_FREE +#define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE +#endif + +/* + * 7.17.2 Initialization. + */ + +#define ATOMIC_VAR_INIT(value) (value) +#define atomic_init(obj, value) __c11_atomic_init(obj, value) + +/* + * Clang and recent GCC both provide predefined macros for the memory + * orderings. If we are using a compiler that doesn't define them, use the + * clang values - these will be ignored in the fallback path. + */ + +#ifndef __ATOMIC_RELAXED +#define __ATOMIC_RELAXED 0 +#endif +#ifndef __ATOMIC_CONSUME +#define __ATOMIC_CONSUME 1 +#endif +#ifndef __ATOMIC_ACQUIRE +#define __ATOMIC_ACQUIRE 2 +#endif +#ifndef __ATOMIC_RELEASE +#define __ATOMIC_RELEASE 3 +#endif +#ifndef __ATOMIC_ACQ_REL +#define __ATOMIC_ACQ_REL 4 +#endif +#ifndef __ATOMIC_SEQ_CST +#define __ATOMIC_SEQ_CST 5 +#endif + +/* + * 7.17.3 Order and consistency. + * + * The memory_order_* constants that denote the barrier behaviour of the + * atomic operations. + * The enum values must be identical to those used by the + * C++ <atomic> header. + */ + +typedef enum { + memory_order_relaxed = __ATOMIC_RELAXED, + memory_order_consume = __ATOMIC_CONSUME, + memory_order_acquire = __ATOMIC_ACQUIRE, + memory_order_release = __ATOMIC_RELEASE, + memory_order_acq_rel = __ATOMIC_ACQ_REL, + memory_order_seq_cst = __ATOMIC_SEQ_CST +} memory_order; + +/* + * 7.17.4 Fences. + */ + +static __inline void atomic_thread_fence(memory_order __order __attribute__((unused))) { + __c11_atomic_thread_fence(__order); +} + +static __inline void atomic_signal_fence(memory_order __order __attribute__((unused))) { + __c11_atomic_signal_fence(__order); +} + +/* + * 7.17.5 Lock-free property. + */ + +#define atomic_is_lock_free(obj) __c11_atomic_is_lock_free(sizeof(*(obj))) + +/* + * 7.17.6 Atomic integer types. + */ + +typedef _Atomic(bool) atomic_bool; +typedef _Atomic(char) atomic_char; +typedef _Atomic(signed char) atomic_schar; +typedef _Atomic(unsigned char) atomic_uchar; +typedef _Atomic(short) atomic_short; +typedef _Atomic(unsigned short) atomic_ushort; +typedef _Atomic(int) atomic_int; +typedef _Atomic(unsigned int) atomic_uint; +typedef _Atomic(long) atomic_long; +typedef _Atomic(unsigned long) atomic_ulong; +typedef _Atomic(long long) atomic_llong; +typedef _Atomic(unsigned long long) atomic_ullong; +#if defined(__BIONIC__) || (defined(__cplusplus) && __cplusplus >= 201103L) + typedef _Atomic(char16_t) atomic_char16_t; + typedef _Atomic(char32_t) atomic_char32_t; +#endif +typedef _Atomic(wchar_t) atomic_wchar_t; +typedef _Atomic(int_least8_t) atomic_int_least8_t; +typedef _Atomic(uint_least8_t) atomic_uint_least8_t; +typedef _Atomic(int_least16_t) atomic_int_least16_t; +typedef _Atomic(uint_least16_t) atomic_uint_least16_t; +typedef _Atomic(int_least32_t) atomic_int_least32_t; +typedef _Atomic(uint_least32_t) atomic_uint_least32_t; +typedef _Atomic(int_least64_t) atomic_int_least64_t; +typedef _Atomic(uint_least64_t) atomic_uint_least64_t; +typedef _Atomic(int_fast8_t) atomic_int_fast8_t; +typedef _Atomic(uint_fast8_t) atomic_uint_fast8_t; +typedef _Atomic(int_fast16_t) atomic_int_fast16_t; +typedef _Atomic(uint_fast16_t) atomic_uint_fast16_t; +typedef _Atomic(int_fast32_t) atomic_int_fast32_t; +typedef _Atomic(uint_fast32_t) atomic_uint_fast32_t; +typedef _Atomic(int_fast64_t) atomic_int_fast64_t; +typedef _Atomic(uint_fast64_t) atomic_uint_fast64_t; +typedef _Atomic(intptr_t) atomic_intptr_t; +typedef _Atomic(uintptr_t) atomic_uintptr_t; +typedef _Atomic(size_t) atomic_size_t; +typedef _Atomic(ptrdiff_t) atomic_ptrdiff_t; +typedef _Atomic(intmax_t) atomic_intmax_t; +typedef _Atomic(uintmax_t) atomic_uintmax_t; + +/* + * 7.17.7 Operations on atomic types. + */ + +/* + * Compiler-specific operations. + */ + +#define atomic_compare_exchange_strong_explicit(object, expected, \ + desired, success, failure) \ + __c11_atomic_compare_exchange_strong(object, expected, desired, \ + success, failure) +#define atomic_compare_exchange_weak_explicit(object, expected, \ + desired, success, failure) \ + __c11_atomic_compare_exchange_weak(object, expected, desired, \ + success, failure) +#define atomic_exchange_explicit(object, desired, order) \ + __c11_atomic_exchange(object, desired, order) +#define atomic_fetch_add_explicit(object, operand, order) \ + __c11_atomic_fetch_add(object, operand, order) +#define atomic_fetch_and_explicit(object, operand, order) \ + __c11_atomic_fetch_and(object, operand, order) +#define atomic_fetch_or_explicit(object, operand, order) \ + __c11_atomic_fetch_or(object, operand, order) +#define atomic_fetch_sub_explicit(object, operand, order) \ + __c11_atomic_fetch_sub(object, operand, order) +#define atomic_fetch_xor_explicit(object, operand, order) \ + __c11_atomic_fetch_xor(object, operand, order) +#define atomic_load_explicit(object, order) \ + __c11_atomic_load(object, order) +#define atomic_store_explicit(object, desired, order) \ + __c11_atomic_store(object, desired, order) + +/* + * Convenience functions. + */ + +#define atomic_compare_exchange_strong(object, expected, desired) \ + atomic_compare_exchange_strong_explicit(object, expected, \ + desired, memory_order_seq_cst, memory_order_seq_cst) +#define atomic_compare_exchange_weak(object, expected, desired) \ + atomic_compare_exchange_weak_explicit(object, expected, \ + desired, memory_order_seq_cst, memory_order_seq_cst) +#define atomic_exchange(object, desired) \ + atomic_exchange_explicit(object, desired, memory_order_seq_cst) +#define atomic_fetch_add(object, operand) \ + atomic_fetch_add_explicit(object, operand, memory_order_seq_cst) +#define atomic_fetch_and(object, operand) \ + atomic_fetch_and_explicit(object, operand, memory_order_seq_cst) +#define atomic_fetch_or(object, operand) \ + atomic_fetch_or_explicit(object, operand, memory_order_seq_cst) +#define atomic_fetch_sub(object, operand) \ + atomic_fetch_sub_explicit(object, operand, memory_order_seq_cst) +#define atomic_fetch_xor(object, operand) \ + atomic_fetch_xor_explicit(object, operand, memory_order_seq_cst) +#define atomic_load(object) \ + atomic_load_explicit(object, memory_order_seq_cst) +#define atomic_store(object, desired) \ + atomic_store_explicit(object, desired, memory_order_seq_cst) + +/* + * 7.17.8 Atomic flag type and operations. + * + * XXX: Assume atomic_bool can be used as an atomic_flag. Is there some + * kind of compiler built-in type we could use? + */ + +typedef struct { + atomic_bool __flag; +} atomic_flag; + +#define ATOMIC_FLAG_INIT { ATOMIC_VAR_INIT(false) } + +static __inline bool atomic_flag_test_and_set_explicit(volatile atomic_flag *__object, memory_order __order) { + return (atomic_exchange_explicit(&__object->__flag, 1, __order)); +} + +static __inline void atomic_flag_clear_explicit(volatile atomic_flag *__object, memory_order __order) { + atomic_store_explicit(&__object->__flag, 0, __order); +} + +static __inline bool atomic_flag_test_and_set(volatile atomic_flag *__object) { + return (atomic_flag_test_and_set_explicit(__object, memory_order_seq_cst)); +} + +static __inline void atomic_flag_clear(volatile atomic_flag *__object) { + atomic_flag_clear_explicit(__object, memory_order_seq_cst); +} diff --git a/libc/include/bits/timespec.h b/libc/include/bits/timespec.h index 0497cfe1f..daad03f52 100644 --- a/libc/include/bits/timespec.h +++ b/libc/include/bits/timespec.h @@ -46,7 +46,7 @@ struct timespec { /** Number of seconds. */ time_t tv_sec; - /** Number of nanoseconds. Must be less than 1,000,000. */ + /** Number of nanoseconds. Must be less than 1,000,000,000. */ long tv_nsec; }; #endif diff --git a/libc/include/pthread.h b/libc/include/pthread.h index 724e5b71d..31509b49f 100644 --- a/libc/include/pthread.h +++ b/libc/include/pthread.h @@ -121,6 +121,8 @@ int pthread_condattr_setclock(pthread_condattr_t* __attr, clockid_t __clock) __I int pthread_condattr_setpshared(pthread_condattr_t* __attr, int __shared); int pthread_cond_broadcast(pthread_cond_t* __cond); +int pthread_cond_clockwait(pthread_cond_t* __cond, pthread_mutex_t* __mutex, clockid_t __clock, + const struct timespec* __timeout) __INTRODUCED_IN(30); int pthread_cond_destroy(pthread_cond_t* __cond); int pthread_cond_init(pthread_cond_t* __cond, const pthread_condattr_t* __attr); int pthread_cond_signal(pthread_cond_t* __cond); @@ -130,8 +132,10 @@ int pthread_cond_timedwait(pthread_cond_t* __cond, pthread_mutex_t* __mutex, con * typically inappropriate, since that clock can change dramatically, causing the timeout to * either expire earlier or much later than intended. * Condition variables have an initialization option to use CLOCK_MONOTONIC, and in addition, - * Android provides this API to use CLOCK_MONOTONIC on a condition variable for this single wait - * no matter how it was initialized. + * Android provides pthread_cond_timedwait_monotonic_np to use CLOCK_MONOTONIC on a condition + * variable for this single wait no matter how it was initialized. + * Note that pthread_cond_clockwait() allows specifying an arbitrary clock and has superseded this + * function. */ int pthread_cond_timedwait_monotonic_np(pthread_cond_t* __cond, pthread_mutex_t* __mutex, const struct timespec* __timeout) __INTRODUCED_IN_64(28); @@ -181,6 +185,8 @@ int pthread_mutexattr_setpshared(pthread_mutexattr_t* __attr, int __shared); int pthread_mutexattr_settype(pthread_mutexattr_t* __attr, int __type); int pthread_mutexattr_setprotocol(pthread_mutexattr_t* __attr, int __protocol) __INTRODUCED_IN(28); +int pthread_mutex_clocklock(pthread_mutex_t* __mutex, clockid_t __clock, + const struct timespec* __abstime) __INTRODUCED_IN(30); int pthread_mutex_destroy(pthread_mutex_t* __mutex); int pthread_mutex_init(pthread_mutex_t* __mutex, const pthread_mutexattr_t* __attr); int pthread_mutex_lock(pthread_mutex_t* __mutex); @@ -188,11 +194,13 @@ int pthread_mutex_timedlock(pthread_mutex_t* __mutex, const struct timespec* __t __INTRODUCED_IN(21); /* - * POSIX only supports using pthread_mutex_timedlock() with CLOCK_REALTIME, however that is - * typically inappropriate, since that clock can change dramatically, causing the timeout to + * POSIX historically only supported using pthread_mutex_timedlock() with CLOCK_REALTIME, however + * that is typically inappropriate, since that clock can change dramatically, causing the timeout to * either expire earlier or much later than intended. * This function is added to use a timespec based on CLOCK_MONOTONIC that does not suffer * from this issue. + * Note that pthread_mutex_clocklock() allows specifying an arbitrary clock and has superseded this + * function. */ int pthread_mutex_timedlock_monotonic_np(pthread_mutex_t* __mutex, const struct timespec* __timeout) __INTRODUCED_IN(28); @@ -226,6 +234,10 @@ int pthread_rwlockattr_getkind_np(const pthread_rwlockattr_t* __attr, int* __kin __INTRODUCED_IN(23); int pthread_rwlockattr_setkind_np(pthread_rwlockattr_t* __attr, int __kind) __INTRODUCED_IN(23); +int pthread_rwlock_clockrdlock(pthread_rwlock_t* __rwlock, clockid_t __clock, + const struct timespec* __timeout) __INTRODUCED_IN(30); +int pthread_rwlock_clockwrlock(pthread_rwlock_t* __rwlock, clockid_t __clock, + const struct timespec* __timeout) __INTRODUCED_IN(30); int pthread_rwlock_destroy(pthread_rwlock_t* __rwlock); int pthread_rwlock_init(pthread_rwlock_t* __rwlock, const pthread_rwlockattr_t* __attr); int pthread_rwlock_rdlock(pthread_rwlock_t* __rwlock); diff --git a/libc/include/semaphore.h b/libc/include/semaphore.h index 01d685b4b..5d66f7ec0 100644 --- a/libc/include/semaphore.h +++ b/libc/include/semaphore.h @@ -30,6 +30,7 @@ #define _SEMAPHORE_H #include <sys/cdefs.h> +#include <sys/types.h> __BEGIN_DECLS @@ -44,16 +45,19 @@ typedef struct { #define SEM_FAILED __BIONIC_CAST(reinterpret_cast, sem_t*, 0) +int sem_clockwait(sem_t* __sem, clockid_t __clock, const struct timespec* __ts) __INTRODUCED_IN(30); int sem_destroy(sem_t* __sem); int sem_getvalue(sem_t* __sem, int* __value); int sem_init(sem_t* __sem, int __shared, unsigned int __value); int sem_post(sem_t* __sem); int sem_timedwait(sem_t* __sem, const struct timespec* __ts); /* - * POSIX only supports using sem_timedwait() with CLOCK_REALTIME, however that is typically - * inappropriate, since that clock can change dramatically, causing the timeout to either + * POSIX historically only supported using sem_timedwait() with CLOCK_REALTIME, however that is + * typically inappropriate, since that clock can change dramatically, causing the timeout to either * expire earlier or much later than intended. This function is added to use a timespec based * on CLOCK_MONOTONIC that does not suffer from this issue. + * Note that sem_clockwait() allows specifying an arbitrary clock and has superseded this + * function. */ int sem_timedwait_monotonic_np(sem_t* __sem, const struct timespec* __ts) __INTRODUCED_IN(28); int sem_trywait(sem_t* __sem); diff --git a/libc/include/stdatomic.h b/libc/include/stdatomic.h index 3c613346d..b7dac4a44 100644 --- a/libc/include/stdatomic.h +++ b/libc/include/stdatomic.h @@ -32,7 +32,7 @@ #include <sys/cdefs.h> -#if defined(__cplusplus) && __cplusplus >= 201103L && defined(_USING_LIBCXX) +#if defined(__cplusplus) && __cplusplus >= 201103L && __has_include(<atomic>) # if __has_feature(cxx_atomic) # define _STDATOMIC_HAVE_ATOMIC # endif @@ -127,260 +127,8 @@ using std::atomic_uintmax_t; #else /* <atomic> unavailable, possibly because this is C, not C++ */ -#include <sys/types.h> -#include <stdbool.h> - -/* - * C: Do it ourselves. - * Note that the runtime representation defined here should be compatible - * with the C++ one, i.e. an _Atomic(T) needs to contain the same - * bits as a T. - */ - -#include <stddef.h> /* For ptrdiff_t. */ -#include <stdint.h> /* TODO: don't drag in all the macros, just the types. */ -// Include uchar.h only when available. Bionic's stdatomic.h is also used for -// the host (via a copy in prebuilts/clang) and uchar.h is not available in the -// glibc used for the host. -#if defined(__BIONIC__) -# include <uchar.h> /* For char16_t and char32_t. */ -#endif - -/* - * 7.17.1 Atomic lock-free macros. - */ - -#ifdef __GCC_ATOMIC_BOOL_LOCK_FREE -#define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE -#endif -#ifdef __GCC_ATOMIC_CHAR_LOCK_FREE -#define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE -#endif -#ifdef __GCC_ATOMIC_CHAR16_T_LOCK_FREE -#define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE -#endif -#ifdef __GCC_ATOMIC_CHAR32_T_LOCK_FREE -#define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE -#endif -#ifdef __GCC_ATOMIC_WCHAR_T_LOCK_FREE -#define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE -#endif -#ifdef __GCC_ATOMIC_SHORT_LOCK_FREE -#define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE -#endif -#ifdef __GCC_ATOMIC_INT_LOCK_FREE -#define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE -#endif -#ifdef __GCC_ATOMIC_LONG_LOCK_FREE -#define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE -#endif -#ifdef __GCC_ATOMIC_LLONG_LOCK_FREE -#define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE -#endif -#ifdef __GCC_ATOMIC_POINTER_LOCK_FREE -#define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE -#endif - -/* - * 7.17.2 Initialization. - */ - -#define ATOMIC_VAR_INIT(value) (value) -#define atomic_init(obj, value) __c11_atomic_init(obj, value) - -/* - * Clang and recent GCC both provide predefined macros for the memory - * orderings. If we are using a compiler that doesn't define them, use the - * clang values - these will be ignored in the fallback path. - */ - -#ifndef __ATOMIC_RELAXED -#define __ATOMIC_RELAXED 0 -#endif -#ifndef __ATOMIC_CONSUME -#define __ATOMIC_CONSUME 1 -#endif -#ifndef __ATOMIC_ACQUIRE -#define __ATOMIC_ACQUIRE 2 -#endif -#ifndef __ATOMIC_RELEASE -#define __ATOMIC_RELEASE 3 -#endif -#ifndef __ATOMIC_ACQ_REL -#define __ATOMIC_ACQ_REL 4 -#endif -#ifndef __ATOMIC_SEQ_CST -#define __ATOMIC_SEQ_CST 5 -#endif - -/* - * 7.17.3 Order and consistency. - * - * The memory_order_* constants that denote the barrier behaviour of the - * atomic operations. - * The enum values must be identical to those used by the - * C++ <atomic> header. - */ - -typedef enum { - memory_order_relaxed = __ATOMIC_RELAXED, - memory_order_consume = __ATOMIC_CONSUME, - memory_order_acquire = __ATOMIC_ACQUIRE, - memory_order_release = __ATOMIC_RELEASE, - memory_order_acq_rel = __ATOMIC_ACQ_REL, - memory_order_seq_cst = __ATOMIC_SEQ_CST -} memory_order; - -/* - * 7.17.4 Fences. - */ - -static __inline void atomic_thread_fence(memory_order __order __attribute__((unused))) { - __c11_atomic_thread_fence(__order); -} - -static __inline void atomic_signal_fence(memory_order __order __attribute__((unused))) { - __c11_atomic_signal_fence(__order); -} - -/* - * 7.17.5 Lock-free property. - */ - -#define atomic_is_lock_free(obj) __c11_atomic_is_lock_free(sizeof(*(obj))) - -/* - * 7.17.6 Atomic integer types. - */ - -typedef _Atomic(bool) atomic_bool; -typedef _Atomic(char) atomic_char; -typedef _Atomic(signed char) atomic_schar; -typedef _Atomic(unsigned char) atomic_uchar; -typedef _Atomic(short) atomic_short; -typedef _Atomic(unsigned short) atomic_ushort; -typedef _Atomic(int) atomic_int; -typedef _Atomic(unsigned int) atomic_uint; -typedef _Atomic(long) atomic_long; -typedef _Atomic(unsigned long) atomic_ulong; -typedef _Atomic(long long) atomic_llong; -typedef _Atomic(unsigned long long) atomic_ullong; -#if defined(__BIONIC__) || (defined(__cplusplus) && __cplusplus >= 201103L) - typedef _Atomic(char16_t) atomic_char16_t; - typedef _Atomic(char32_t) atomic_char32_t; -#endif -typedef _Atomic(wchar_t) atomic_wchar_t; -typedef _Atomic(int_least8_t) atomic_int_least8_t; -typedef _Atomic(uint_least8_t) atomic_uint_least8_t; -typedef _Atomic(int_least16_t) atomic_int_least16_t; -typedef _Atomic(uint_least16_t) atomic_uint_least16_t; -typedef _Atomic(int_least32_t) atomic_int_least32_t; -typedef _Atomic(uint_least32_t) atomic_uint_least32_t; -typedef _Atomic(int_least64_t) atomic_int_least64_t; -typedef _Atomic(uint_least64_t) atomic_uint_least64_t; -typedef _Atomic(int_fast8_t) atomic_int_fast8_t; -typedef _Atomic(uint_fast8_t) atomic_uint_fast8_t; -typedef _Atomic(int_fast16_t) atomic_int_fast16_t; -typedef _Atomic(uint_fast16_t) atomic_uint_fast16_t; -typedef _Atomic(int_fast32_t) atomic_int_fast32_t; -typedef _Atomic(uint_fast32_t) atomic_uint_fast32_t; -typedef _Atomic(int_fast64_t) atomic_int_fast64_t; -typedef _Atomic(uint_fast64_t) atomic_uint_fast64_t; -typedef _Atomic(intptr_t) atomic_intptr_t; -typedef _Atomic(uintptr_t) atomic_uintptr_t; -typedef _Atomic(size_t) atomic_size_t; -typedef _Atomic(ptrdiff_t) atomic_ptrdiff_t; -typedef _Atomic(intmax_t) atomic_intmax_t; -typedef _Atomic(uintmax_t) atomic_uintmax_t; - -/* - * 7.17.7 Operations on atomic types. - */ - -/* - * Compiler-specific operations. - */ - -#define atomic_compare_exchange_strong_explicit(object, expected, \ - desired, success, failure) \ - __c11_atomic_compare_exchange_strong(object, expected, desired, \ - success, failure) -#define atomic_compare_exchange_weak_explicit(object, expected, \ - desired, success, failure) \ - __c11_atomic_compare_exchange_weak(object, expected, desired, \ - success, failure) -#define atomic_exchange_explicit(object, desired, order) \ - __c11_atomic_exchange(object, desired, order) -#define atomic_fetch_add_explicit(object, operand, order) \ - __c11_atomic_fetch_add(object, operand, order) -#define atomic_fetch_and_explicit(object, operand, order) \ - __c11_atomic_fetch_and(object, operand, order) -#define atomic_fetch_or_explicit(object, operand, order) \ - __c11_atomic_fetch_or(object, operand, order) -#define atomic_fetch_sub_explicit(object, operand, order) \ - __c11_atomic_fetch_sub(object, operand, order) -#define atomic_fetch_xor_explicit(object, operand, order) \ - __c11_atomic_fetch_xor(object, operand, order) -#define atomic_load_explicit(object, order) \ - __c11_atomic_load(object, order) -#define atomic_store_explicit(object, desired, order) \ - __c11_atomic_store(object, desired, order) - -/* - * Convenience functions. - */ - -#define atomic_compare_exchange_strong(object, expected, desired) \ - atomic_compare_exchange_strong_explicit(object, expected, \ - desired, memory_order_seq_cst, memory_order_seq_cst) -#define atomic_compare_exchange_weak(object, expected, desired) \ - atomic_compare_exchange_weak_explicit(object, expected, \ - desired, memory_order_seq_cst, memory_order_seq_cst) -#define atomic_exchange(object, desired) \ - atomic_exchange_explicit(object, desired, memory_order_seq_cst) -#define atomic_fetch_add(object, operand) \ - atomic_fetch_add_explicit(object, operand, memory_order_seq_cst) -#define atomic_fetch_and(object, operand) \ - atomic_fetch_and_explicit(object, operand, memory_order_seq_cst) -#define atomic_fetch_or(object, operand) \ - atomic_fetch_or_explicit(object, operand, memory_order_seq_cst) -#define atomic_fetch_sub(object, operand) \ - atomic_fetch_sub_explicit(object, operand, memory_order_seq_cst) -#define atomic_fetch_xor(object, operand) \ - atomic_fetch_xor_explicit(object, operand, memory_order_seq_cst) -#define atomic_load(object) \ - atomic_load_explicit(object, memory_order_seq_cst) -#define atomic_store(object, desired) \ - atomic_store_explicit(object, desired, memory_order_seq_cst) - -/* - * 7.17.8 Atomic flag type and operations. - * - * XXX: Assume atomic_bool can be used as an atomic_flag. Is there some - * kind of compiler built-in type we could use? - */ - -typedef struct { - atomic_bool __flag; -} atomic_flag; - -#define ATOMIC_FLAG_INIT { ATOMIC_VAR_INIT(false) } - -static __inline bool atomic_flag_test_and_set_explicit(volatile atomic_flag *__object, memory_order __order) { - return (atomic_exchange_explicit(&__object->__flag, 1, __order)); -} - -static __inline void atomic_flag_clear_explicit(volatile atomic_flag *__object, memory_order __order) { - atomic_store_explicit(&__object->__flag, 0, __order); -} - -static __inline bool atomic_flag_test_and_set(volatile atomic_flag *__object) { - return (atomic_flag_test_and_set_explicit(__object, memory_order_seq_cst)); -} - -static __inline void atomic_flag_clear(volatile atomic_flag *__object) { - atomic_flag_clear_explicit(__object, memory_order_seq_cst); -} +/* Actual implementation is in bits/stdatomic.h since our test code is C++. */ +#include <bits/stdatomic.h> #endif /* <atomic> unavailable */ diff --git a/libc/include/stdio.h b/libc/include/stdio.h index 8bd690fec..6632c0170 100644 --- a/libc/include/stdio.h +++ b/libc/include/stdio.h @@ -165,9 +165,53 @@ char* tmpnam(char* __s) char* tempnam(const char* __dir, const char* __prefix) __warnattr("tempnam is unsafe, use mkstemp or tmpfile instead"); +/** + * [rename(2)](http://man7.org/linux/man-pages/man2/rename.2.html) changes + * the name or location of a file. + * + * Returns 0 on success, and returns -1 and sets `errno` on failure. + */ int rename(const char* __old_path, const char* __new_path); + +/** + * [renameat(2)](http://man7.org/linux/man-pages/man2/renameat.2.html) changes + * the name or location of a file, interpreting relative paths using an fd. + * + * Returns 0 on success, and returns -1 and sets `errno` on failure. + */ int renameat(int __old_dir_fd, const char* __old_path, int __new_dir_fd, const char* __new_path); +#if defined(__USE_GNU) + +/** + * Flag for [renameat2(2)](http://man7.org/linux/man-pages/man2/renameat2.2.html) + * to fail if the new path already exists. + */ +#define RENAME_NOREPLACE (1<<0) + +/** + * Flag for [renameat2(2)](http://man7.org/linux/man-pages/man2/renameat2.2.html) + * to atomically exchange the two paths. + */ +#define RENAME_EXCHANGE (1<<1) + +/** + * Flag for [renameat2(2)](http://man7.org/linux/man-pages/man2/renameat2.2.html) + * to create a union/overlay filesystem object. + */ +#define RENAME_WHITEOUT (1<<2) + +/** + * [renameat2(2)](http://man7.org/linux/man-pages/man2/renameat2.2.html) changes + * the name or location of a file, interpreting relative paths using an fd, + * with optional `RENAME_` flags. + * + * Returns 0 on success, and returns -1 and sets `errno` on failure. + */ +int renameat2(int __old_dir_fd, const char* __old_path, int __new_dir_fd, const char* __new_path, unsigned __flags) __INTRODUCED_IN(30); + +#endif + int fseek(FILE* __fp, long __offset, int __whence); long ftell(FILE* __fp); diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h index d5b861983..b66e3c64e 100644 --- a/libc/include/stdlib.h +++ b/libc/include/stdlib.h @@ -90,7 +90,7 @@ int atoi(const char* __s) __attribute_pure__; long atol(const char* __s) __attribute_pure__; long long atoll(const char* __s) __attribute_pure__; -char* realpath(const char* __path, char* __resolved); +__wur char* realpath(const char* __path, char* __resolved); int system(const char* __command); void* bsearch(const void* __key, const void* __base, size_t __nmemb, size_t __size, int (*__comparator)(const void* __lhs, const void* __rhs)); diff --git a/libc/include/strings.h b/libc/include/strings.h index ccdac044c..a054aed55 100644 --- a/libc/include/strings.h +++ b/libc/include/strings.h @@ -51,17 +51,15 @@ __BEGIN_DECLS -#if defined(__BIONIC_FORTIFY) /** Deprecated. Use memmove() instead. */ -#define bcopy(b1, b2, len) (void)(__builtin___memmove_chk((b2), (b1), (len), __bos0(b2))) -/** Deprecated. Use memset() instead. */ -#define bzero(b, len) (void)(__builtin___memset_chk((b), '\0', (len), __bos0(b))) -#else -/** Deprecated. Use memmove() instead. */ -#define bcopy(b1, b2, len) (void)(__builtin_memmove((b2), (b1), (len))) +static __inline__ __always_inline void bcopy(const void* b1, void* b2, size_t len) { + __builtin_memmove(b2, b1, len); +} + /** Deprecated. Use memset() instead. */ -#define bzero(b, len) (void)(__builtin_memset((b), '\0', (len))) -#endif +static __inline__ __always_inline void bzero(void* b, size_t len) { + __builtin_memset(b, 0, len); +} #if !defined(__i386__) || __ANDROID_API__ >= __ANDROID_API_J_MR2__ /** @@ -72,6 +70,10 @@ __BEGIN_DECLS int ffs(int __i) __INTRODUCED_IN_X86(18); #endif +#if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS) +#include <bits/fortify/strings.h> +#endif + __END_DECLS #include <android/legacy_strings_inlines.h> diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h index dceb1165c..689b65031 100644 --- a/libc/include/sys/cdefs.h +++ b/libc/include/sys/cdefs.h @@ -361,3 +361,6 @@ int __size_mul_overflow(__SIZE_TYPE__ a, __SIZE_TYPE__ b, __SIZE_TYPE__ *result) #include <android/versioning.h> #include <android/api-level.h> +#if __has_include(<android/ndk-version.h>) +#include <android/ndk-version.h> +#endif diff --git a/libc/include/sys/mman.h b/libc/include/sys/mman.h index 89d6d07c3..3b83229d7 100644 --- a/libc/include/sys/mman.h +++ b/libc/include/sys/mman.h @@ -26,34 +26,27 @@ * SUCH DAMAGE. */ -#ifndef _SYS_MMAN_H_ -#define _SYS_MMAN_H_ +#pragma once #include <sys/cdefs.h> #include <sys/types.h> +#include <linux/memfd.h> #include <linux/mman.h> __BEGIN_DECLS -#ifndef MAP_ANON -#define MAP_ANON MAP_ANONYMOUS -#endif +/** Alternative spelling of the `MAP_ANONYMOUS` flag for mmap(). */ +#define MAP_ANON MAP_ANONYMOUS +/** Return value for mmap(). */ #define MAP_FAILED __BIONIC_CAST(reinterpret_cast, void*, -1) -#define MREMAP_MAYMOVE 1 -#define MREMAP_FIXED 2 - -/* - * See https://android.googlesource.com/platform/bionic/+/master/docs/32-bit-abi.md - * - * mmap64 wasn't really around until L, but we added an inline for it since it - * allows a lot more code to compile with _FILE_OFFSET_BITS=64. +/** + * [mmap(2)](http://man7.org/linux/man-pages/man2/mmap.2.html) + * creates a memory mapping for the given range. * - * GCC removes the static inline unless it is explicitly used. We can get around - * this with __attribute__((used)), but that needlessly adds a definition of - * mmap64 to every translation unit that includes this header. Instead, just - * preserve the old behavior for GCC and emit a useful diagnostic. + * Returns the address of the mapping on success, + * and returns `MAP_FAILED` and sets `errno` on failure. */ #if defined(__USE_FILE_OFFSET64) void* mmap(void* __addr, size_t __size, int __prot, int __flags, int __fd, off_t __offset) __RENAME(mmap64); @@ -62,25 +55,126 @@ void* mmap(void* __addr, size_t __size, int __prot, int __flags, int __fd, off_t #endif #if __ANDROID_API__ >= __ANDROID_API_L__ +/** + * mmap64() is a variant of mmap() that takes a 64-bit offset even on LP32. + * + * See https://android.googlesource.com/platform/bionic/+/master/docs/32-bit-abi.md + * + * mmap64 wasn't really around until L, but we added an inline for it since it + * allows a lot more code to compile with _FILE_OFFSET_BITS=64. + */ void* mmap64(void* __addr, size_t __size, int __prot, int __flags, int __fd, off64_t __offset) __INTRODUCED_IN(21); #endif +/** + * [munmap(2)](http://man7.org/linux/man-pages/man2/munmap.2.html) + * deletes a memory mapping for the given range. + * + * Returns 0 on success, and returns -1 and sets `errno` on failure. + */ int munmap(void* __addr, size_t __size); + +/** + * [msync(2)](http://man7.org/linux/man-pages/man2/msync.2.html) + * flushes changes to a memory-mapped file to disk. + * + * Returns 0 on success, and returns -1 and sets `errno` on failure. + */ int msync(void* __addr, size_t __size, int __flags); + +/** + * [mprotect(2)](http://man7.org/linux/man-pages/man2/mprotect.2.html) + * sets the protection on a memory region. + * + * Returns 0 on success, and returns -1 and sets `errno` on failure. + */ int mprotect(void* __addr, size_t __size, int __prot); + +/** Flag for mremap(). */ +#define MREMAP_MAYMOVE 1 + +/** Flag for mremap(). */ +#define MREMAP_FIXED 2 + +/** + * [mremap(2)](http://man7.org/linux/man-pages/man2/mremap.2.html) + * expands or shrinks an existing memory mapping. + * + * Returns the address of the mapping on success, + * and returns `MAP_FAILED` and sets `errno` on failure. + */ void* mremap(void* __old_addr, size_t __old_size, size_t __new_size, int __flags, ...); +/** + * [mlockall(2)](http://man7.org/linux/man-pages/man2/mlockall.2.html) + * locks pages (preventing swapping). + * + * Returns 0 on success, and returns -1 and sets `errno` on failure. + */ int mlockall(int __flags) __INTRODUCED_IN(17); + +/** + * [munlockall(2)](http://man7.org/linux/man-pages/man2/munlockall.2.html) + * unlocks pages (allowing swapping). + * + * Returns 0 on success, and returns -1 and sets `errno` on failure. + */ int munlockall(void) __INTRODUCED_IN(17); +/** + * [mlock(2)](http://man7.org/linux/man-pages/man2/mlock.2.html) + * locks pages (preventing swapping). + * + * Returns 0 on success, and returns -1 and sets `errno` on failure. + */ int mlock(const void* __addr, size_t __size); + +/** + * [mlock2(2)](http://man7.org/linux/man-pages/man2/mlock.2.html) + * locks pages (preventing swapping), with optional flags. + * + * Returns 0 on success, and returns -1 and sets `errno` on failure. + */ +int mlock2(const void* __addr, size_t __size, int __flags) __INTRODUCED_IN(30); + +/** + * [munlock(2)](http://man7.org/linux/man-pages/man2/munlock.2.html) + * unlocks pages (allowing swapping). + * + * Returns 0 on success, and returns -1 and sets `errno` on failure. + */ int munlock(const void* __addr, size_t __size); +/** + * [mincore(2)](http://man7.org/linux/man-pages/man2/mincore.2.html) + * tests whether pages are resident in memory. + * + * Returns 0 on success, and returns -1 and sets `errno` on failure. + */ int mincore(void* __addr, size_t __size, unsigned char* __vector); +/** + * [madvise(2)](http://man7.org/linux/man-pages/man2/madvise.2.html) + * gives the kernel advice about future usage patterns. + * + * Returns 0 on success, and returns -1 and sets `errno` on failure. + */ int madvise(void* __addr, size_t __size, int __advice); +#if defined(__USE_GNU) + +/** + * [memfd_create(2)](http://man7.org/linux/man-pages/man2/memfd_create.2.html) + * creates an anonymous file. + * + * Returns an fd on success, and returns -1 and sets `errno` on failure. + */ +int memfd_create(const char* __name, unsigned __flags) __INTRODUCED_IN(30); + +#endif + #if __ANDROID_API__ >= __ANDROID_API_M__ + /* * Some third-party code uses the existence of POSIX_MADV_NORMAL to detect the * availability of posix_madvise. This is not correct, since having up-to-date @@ -89,16 +183,30 @@ int madvise(void* __addr, size_t __size, int __advice); * * https://github.com/android-ndk/ndk/issues/395 */ + +/** Flag for posix_madvise(). */ #define POSIX_MADV_NORMAL MADV_NORMAL +/** Flag for posix_madvise(). */ #define POSIX_MADV_RANDOM MADV_RANDOM +/** Flag for posix_madvise(). */ #define POSIX_MADV_SEQUENTIAL MADV_SEQUENTIAL +/** Flag for posix_madvise(). */ #define POSIX_MADV_WILLNEED MADV_WILLNEED +/** Flag for posix_madvise(). */ #define POSIX_MADV_DONTNEED MADV_DONTNEED + #endif + +/** + * [posix_madvise(3)](http://man7.org/linux/man-pages/man3/posix_madvise.3.html) + * gives the kernel advice about future usage patterns. + * + * Returns 0 on success, and returns a positive error number on failure. + * + * See also madvise() which has been available much longer. + */ int posix_madvise(void* __addr, size_t __size, int __advice) __INTRODUCED_IN(23); __END_DECLS #include <android/legacy_sys_mman_inlines.h> - -#endif |