Merge "Introduce hwasan mode for linker"
diff --git a/android-changes-for-ndk-developers.md b/android-changes-for-ndk-developers.md
index c5a6ac3..8ffd96f 100644
--- a/android-changes-for-ndk-developers.md
+++ b/android-changes-for-ndk-developers.md
@@ -107,7 +107,7 @@
## Correct soname/path handling (Available in API level >= 23)
The dynamic linker now understands the difference
-between a library’s soname and its path (public bug
+between a library’s soname and its path (public bug
https://code.google.com/p/android/issues/detail?id=6670). API level 23
is the first release where search by soname is implemented. Earlier
releases would assume that the basename of the library was the soname,
@@ -326,12 +326,12 @@
## Missing SONAME (Enforced for API level >= 23)
-Each ELF shared object (“native library”) must have a SONAME (Shared
-Object Name) attribute. The NDK toolchain adds this attribute by default,
-so its absence indicates either a misconfigured alternative toolchain
-or a misconfiguration in your build system. A missing SONAME may lead
-to runtime issues such as the wrong library being loaded: the filename
-is used instead when this attribute is missing.
+Each ELF shared object (“native library”) must have a SONAME
+(Shared Object Name) attribute. The NDK build systems add this
+attribute by default, so its absence (or an incorrect soname) indicates
+a misconfiguration in your build system. A missing SONAME may lead to
+runtime issues such as the wrong library being loaded: the filename is
+used instead when this attribute is missing.
```
$ readelf --dynamic libWithSoName.so | grep SONAME
@@ -346,7 +346,7 @@
*Resolution*: the current NDK generates the correct SONAME by
default. Ensure you're using the current NDK and that you haven't
configured your build system to generate incorrect SONAME entries (using
-the -soname linker option).
+the `-soname` linker option).
## `__register_atfork` (Available in API level >= 23)
diff --git a/libc/Android.bp b/libc/Android.bp
index 1a7a1af..6ca9503 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -1318,7 +1318,7 @@
// ========================================================
genrule {
- name: "syscalls-arm.S",
+ name: "syscalls-arm",
out: ["syscalls-arm.S"],
srcs: ["SYSCALLS.TXT"],
tools: ["gensyscalls"],
@@ -1326,7 +1326,7 @@
}
genrule {
- name: "syscalls-arm64.S",
+ name: "syscalls-arm64",
out: ["syscalls-arm64.S"],
srcs: ["SYSCALLS.TXT"],
tools: ["gensyscalls"],
@@ -1334,7 +1334,7 @@
}
genrule {
- name: "syscalls-riscv64.S",
+ name: "syscalls-riscv64",
out: ["syscalls-riscv64.S"],
srcs: ["SYSCALLS.TXT"],
tools: ["gensyscalls"],
@@ -1342,7 +1342,7 @@
}
genrule {
- name: "syscalls-x86.S",
+ name: "syscalls-x86",
out: ["syscalls-x86.S"],
srcs: ["SYSCALLS.TXT"],
tools: ["gensyscalls"],
@@ -1350,7 +1350,7 @@
}
genrule {
- name: "syscalls-x86_64.S",
+ name: "syscalls-x86_64",
out: ["syscalls-x86_64.S"],
srcs: ["SYSCALLS.TXT"],
tools: ["gensyscalls"],
@@ -1362,19 +1362,19 @@
srcs: ["bionic/__set_errno.cpp"],
arch: {
arm: {
- srcs: [":syscalls-arm.S"],
+ srcs: [":syscalls-arm"],
},
arm64: {
- srcs: [":syscalls-arm64.S"],
+ srcs: [":syscalls-arm64"],
},
riscv64: {
- srcs: [":syscalls-riscv64.S"],
+ srcs: [":syscalls-riscv64"],
},
x86: {
- srcs: [":syscalls-x86.S"],
+ srcs: [":syscalls-x86"],
},
x86_64: {
- srcs: [":syscalls-x86_64.S"],
+ srcs: [":syscalls-x86_64"],
},
},
name: "libc_syscalls",
@@ -1872,7 +1872,7 @@
genrule {
name: "libc.arm.map",
- out: ["libc.arm.map"],
+ out: ["libc.arm.map.txt"],
srcs: ["libc.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) arm $(in) $(out)",
@@ -1880,7 +1880,7 @@
genrule {
name: "libc.arm64.map",
- out: ["libc.arm64.map"],
+ out: ["libc.arm64.map.txt"],
srcs: ["libc.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) arm64 $(in) $(out)",
@@ -1888,7 +1888,7 @@
genrule {
name: "libc.riscv64.map",
- out: ["libc.riscv64.map"],
+ out: ["libc.riscv64.map.txt"],
srcs: ["libc.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) riscv64 $(in) $(out)",
@@ -1896,7 +1896,7 @@
genrule {
name: "libc.x86.map",
- out: ["libc.x86.map"],
+ out: ["libc.x86.map.txt"],
srcs: ["libc.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) x86 $(in) $(out)",
@@ -1904,7 +1904,7 @@
genrule {
name: "libc.x86_64.map",
- out: ["libc.x86_64.map"],
+ out: ["libc.x86_64.map.txt"],
srcs: ["libc.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) x86_64 $(in) $(out)",
@@ -2109,7 +2109,7 @@
genrule {
name: "libstdc++.arm.map",
- out: ["libstdc++.arm.map"],
+ out: ["libstdc++.arm.map.txt"],
srcs: ["libstdc++.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) arm $(in) $(out)",
@@ -2117,7 +2117,7 @@
genrule {
name: "libstdc++.arm64.map",
- out: ["libstdc++.arm64.map"],
+ out: ["libstdc++.arm64.map.txt"],
srcs: ["libstdc++.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) arm64 $(in) $(out)",
@@ -2125,7 +2125,7 @@
genrule {
name: "libstdc++.riscv64.map",
- out: ["libstdc++.riscv64.map"],
+ out: ["libstdc++.riscv64.map.txt"],
srcs: ["libstdc++.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) riscv64 $(in) $(out)",
@@ -2133,7 +2133,7 @@
genrule {
name: "libstdc++.x86.map",
- out: ["libstdc++.x86.map"],
+ out: ["libstdc++.x86.map.txt"],
srcs: ["libstdc++.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) x86 $(in) $(out)",
@@ -2141,7 +2141,7 @@
genrule {
name: "libstdc++.x86_64.map",
- out: ["libstdc++.x86_64.map"],
+ out: ["libstdc++.x86_64.map.txt"],
srcs: ["libstdc++.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) x86_64 $(in) $(out)",
@@ -2182,10 +2182,6 @@
name: "crt_defaults",
defaults: ["crt_and_memtag_defaults"],
system_shared_libs: [],
-
- conlyflags: [
- "-mllvm -disable-check-noreturn-call",
- ]
}
cc_defaults {
@@ -2218,6 +2214,8 @@
srcs: ["arch-common/bionic/crtbrand.S"],
defaults: ["crt_so_defaults"],
+ // crtbrand is an intermediate artifact, not a final CRT object.
+ exclude_from_ndk_sysroot: true,
}
cc_object {
diff --git a/libc/arch-riscv64/bionic/setjmp.S b/libc/arch-riscv64/bionic/setjmp.S
index ba3cacf..26f7ec9 100644
--- a/libc/arch-riscv64/bionic/setjmp.S
+++ b/libc/arch-riscv64/bionic/setjmp.S
@@ -36,50 +36,52 @@
// 0 sigflag/cookie setjmp cookie in top 31 bits, signal mask flag in low bit
// 1 sigmask 64-bit signal mask
// 2 ra
-// 3 s0
+// 3 sp
+// 4 gp
+// 5 s0
// ......
-// 14 s11
-// 15 sp
-// 16 fs0
+// 16 s11
+// 17 fs0
// ......
-// 27 fs11
-// 28 checksum
+// 28 fs11
+// 29 checksum
// _JBLEN: defined in bionic/libc/include/setjmp.h
#define _JB_SIGFLAG 0
#define _JB_SIGMASK 1 * 8
#define _JB_RA 2 * 8
-#define _JB_S0 3 * 8
-#define _JB_S1 4 * 8
-#define _JB_S2 5 * 8
-#define _JB_S3 6 * 8
-#define _JB_S4 7 * 8
-#define _JB_S5 8 * 8
-#define _JB_S6 9 * 8
-#define _JB_S7 10 * 8
-#define _JB_S8 11 * 8
-#define _JB_S9 12 * 8
-#define _JB_S10 13 * 8
-#define _JB_S11 14 * 8
-#define _JB_SP 15 * 8
-#define _JB_FS0 16 * 8
-#define _JB_FS1 17 * 8
-#define _JB_FS2 18 * 8
-#define _JB_FS3 19 * 8
-#define _JB_FS4 20 * 8
-#define _JB_FS5 21 * 8
-#define _JB_FS6 22 * 8
-#define _JB_FS7 23 * 8
-#define _JB_FS8 24 * 8
-#define _JB_FS9 25 * 8
-#define _JB_FS10 26 * 8
-#define _JB_FS11 27 * 8
-#define _JB_CHECKSUM 28 * 8
+#define _JB_SP 3 * 8
+#define _JB_GP 4 * 8
+#define _JB_S0 5 * 8
+#define _JB_S1 6 * 8
+#define _JB_S2 7 * 8
+#define _JB_S3 8 * 8
+#define _JB_S4 9 * 8
+#define _JB_S5 10 * 8
+#define _JB_S6 11 * 8
+#define _JB_S7 12 * 8
+#define _JB_S8 13 * 8
+#define _JB_S9 14 * 8
+#define _JB_S10 15 * 8
+#define _JB_S11 16 * 8
+#define _JB_FS0 17 * 8
+#define _JB_FS1 18 * 8
+#define _JB_FS2 19 * 8
+#define _JB_FS3 20 * 8
+#define _JB_FS4 21 * 8
+#define _JB_FS5 22 * 8
+#define _JB_FS6 23 * 8
+#define _JB_FS7 24 * 8
+#define _JB_FS8 25 * 8
+#define _JB_FS9 26 * 8
+#define _JB_FS10 27 * 8
+#define _JB_FS11 28 * 8
+#define _JB_CHECKSUM 29 * 8
.macro m_mangle_registers reg, sp_reg
xor s0, s0, \reg
xor s1, s1, \reg
- xor a4, a4, \reg // a4 is the masked s2 (x18) for SCS.
+ xor s2, s2, \reg
xor s3, s3, \reg
xor s4, s4, \reg
xor s5, s5, \reg
@@ -89,12 +91,13 @@
xor s9, s9, \reg
xor s10, s10, \reg
xor s11, s11, \reg
+ xor a4, a4, \reg // a4 is the masked gp (x3) for SCS.
xor \sp_reg, \sp_reg, \reg
.endm
.macro m_calculate_checksum dst, src, scratch
li \dst, 0
- .irp i,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27
+ .irp i,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28
ld \scratch, (\i * 8)(\src)
xor \dst, \dst, \scratch
.endr
@@ -152,19 +155,21 @@
andi a1, a1, -2
// Mask off the high bits of the shadow call stack pointer.
- // We only store the low bits of x18 to avoid leaking the
+ // We only store the low bits of gp to avoid leaking the
// shadow call stack address into memory.
// See the SCS commentary in pthread_internal.h for more detail.
li a4, SCS_MASK
- and a4, a4, x18
+ and a4, a4, gp
// Save core registers.
mv a2, sp
m_mangle_registers a1, sp_reg=a2
sd ra, _JB_RA(a0)
+ sd a4, _JB_GP(a0) // a4 is the masked gp (x3) for SCS.
+ sd a2, _JB_SP(a0)
sd s0, _JB_S0(a0)
sd s1, _JB_S1(a0)
- sd a4, _JB_S2(a0) // a4 is the masked s2 (x18) for SCS.
+ sd s2, _JB_S2(a0)
sd s3, _JB_S3(a0)
sd s4, _JB_S4(a0)
sd s5, _JB_S5(a0)
@@ -174,7 +179,6 @@
sd s9, _JB_S9(a0)
sd s10, _JB_S10(a0)
sd s11, _JB_S11(a0)
- sd a2, _JB_SP(a0)
m_unmangle_registers a1, sp_reg=a2
// Save floating point registers.
@@ -236,9 +240,10 @@
// Restore core registers.
andi a2, a2, -2
ld ra, _JB_RA(a0)
+ ld a4, _JB_GP(a0) // Don't clobber the upper bits of gp (x3) used for SCS yet.
ld s0, _JB_S0(a0)
ld s1, _JB_S1(a0)
- ld a4, _JB_S2(a0) // Don't clobber s2 (x18) used for SCS yet.
+ ld s2, _JB_S2(a0)
ld s3, _JB_S3(a0)
ld s4, _JB_S4(a0)
ld s5, _JB_S5(a0)
@@ -254,8 +259,8 @@
// Restore the low bits of the shadow call stack pointer.
li a5, ~SCS_MASK
- and x18, x18, a5
- or x18, a4, x18
+ and gp, gp, a5
+ or gp, gp, a4
addi sp, sp, -24
sd ra, 0(sp)
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index 15d6d6d..7bf9b40 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -133,14 +133,14 @@
size_t scs_offset =
(getpid() == 1) ? 0 : (arc4random_uniform(SCS_GUARD_REGION_SIZE / SCS_SIZE - 1) * SCS_SIZE);
- // Make the stack readable and writable and store its address in x18.
- // This is deliberately the only place where the address is stored.
+ // Make the stack read-write, and store its address in the register we're using as the shadow
+ // stack pointer. This is deliberately the only place where the address is stored.
char* scs = scs_aligned_guard_region + scs_offset;
mprotect(scs, SCS_SIZE, PROT_READ | PROT_WRITE);
#if defined(__aarch64__)
__asm__ __volatile__("mov x18, %0" ::"r"(scs));
#elif defined(__riscv)
- __asm__ __volatile__("mv x18, %0" ::"r"(scs));
+ __asm__ __volatile__("mv gp, %0" ::"r"(scs));
#endif
#endif
}
diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h
index 083c2ed..a3a4ccd 100644
--- a/libc/bionic/pthread_internal.h
+++ b/libc/bionic/pthread_internal.h
@@ -110,7 +110,8 @@
// are actually used.
//
// This address is only used to deallocate the shadow call stack on thread
- // exit; the address of the stack itself is stored only in the x18 register.
+ // exit; the address of the stack itself is stored only in the register used
+ // as the shadow stack pointer (x18 on arm64, gp on riscv64).
//
// Because the protection offered by SCS relies on the secrecy of the stack
// address, storing the address here weakens the protection, but only
@@ -119,22 +120,24 @@
// to other allocations), but not the stack itself, which is <0.1% of the size
// of the guard region.
//
- // longjmp()/setjmp() don't store all the bits of x18, only the bottom bits
- // covered by SCS_MASK. Since longjmp()/setjmp() between different threads is
- // undefined behavior (and unsupported on Android), we can retrieve the high
- // bits of x18 from the current value in x18 --- all the jmp_buf needs to store
- // is where exactly the shadow stack pointer is in the thread's shadow stack:
- // the bottom bits of x18.
+ // longjmp()/setjmp() don't store all the bits of the shadow stack pointer,
+ // only the bottom bits covered by SCS_MASK. Since longjmp()/setjmp() between
+ // different threads is undefined behavior (and unsupported on Android), we
+ // can retrieve the high bits of the shadow stack pointer from the current
+ // value in the register --- all the jmp_buf needs to store is where exactly
+ // the shadow stack pointer is *within* the thread's shadow stack: the bottom
+ // bits of the register.
//
// There are at least two other options for discovering the start address of
// the guard region on thread exit, but they are not as simple as storing in
// TLS.
//
- // 1) Derive it from the value of the x18 register. This is only possible in
- // processes that do not contain legacy code that might clobber x18,
- // therefore each process must declare early during process startup whether
- // it might load legacy code.
- // TODO: riscv64 has no legacy code, so we can actually go this route there!
+ // 1) Derive it from the current value of the shadow stack pointer. This is
+ // only possible in processes that do not contain legacy code that might
+ // clobber x18 on arm64, therefore each process must declare early during
+ // process startup whether it might load legacy code.
+ // TODO: riscv64 has no legacy code, so we can actually go this route
+ // there, but hopefully we'll actually get the Zsslpcfi extension instead.
// 2) Mark the guard region as such using prctl(PR_SET_VMA_ANON_NAME) and
// discover its address by reading /proc/self/maps. One issue with this is
// that reading /proc/self/maps can race with allocations, so we may need
diff --git a/libc/include/android/dlext.h b/libc/include/android/dlext.h
index f0b731c..f216aab 100644
--- a/libc/include/android/dlext.h
+++ b/libc/include/android/dlext.h
@@ -157,7 +157,7 @@
uint64_t flags;
/** Used by `ANDROID_DLEXT_RESERVED_ADDRESS` and `ANDROID_DLEXT_RESERVED_ADDRESS_HINT`. */
- void* reserved_addr;
+ void* _Nullable reserved_addr;
/** Used by `ANDROID_DLEXT_RESERVED_ADDRESS` and `ANDROID_DLEXT_RESERVED_ADDRESS_HINT`. */
size_t reserved_size;
@@ -170,7 +170,7 @@
off64_t library_fd_offset;
/** Used by `ANDROID_DLEXT_USE_NAMESPACE`. */
- struct android_namespace_t* library_namespace;
+ struct android_namespace_t* _Nullable library_namespace;
} android_dlextinfo;
/**
@@ -180,7 +180,7 @@
*
* Available since API level 21.
*/
-void* android_dlopen_ext(const char* __filename, int __flags, const android_dlextinfo* __info)
+void* _Nullable android_dlopen_ext(const char* _Nullable __filename, int __flags, const android_dlextinfo* _Nullable __info)
__INTRODUCED_IN(21);
__END_DECLS
diff --git a/libc/include/android/fdsan.h b/libc/include/android/fdsan.h
index 59ce133..3de0649 100644
--- a/libc/include/android/fdsan.h
+++ b/libc/include/android/fdsan.h
@@ -159,7 +159,7 @@
*
* The return value points to memory with static lifetime, do not attempt to modify it.
*/
-const char* android_fdsan_get_tag_type(uint64_t tag) __INTRODUCED_IN(29);
+const char* _Nonnull android_fdsan_get_tag_type(uint64_t tag) __INTRODUCED_IN(29);
/*
* Get an owner tag's value, with the type masked off.
diff --git a/libc/include/android/legacy_stdlib_inlines.h b/libc/include/android/legacy_stdlib_inlines.h
index e9b606a..f0985fe 100644
--- a/libc/include/android/legacy_stdlib_inlines.h
+++ b/libc/include/android/legacy_stdlib_inlines.h
@@ -38,15 +38,15 @@
__BEGIN_DECLS
-static __inline double strtod_l(const char* __s, char** __end_ptr, locale_t __l) {
+static __inline double strtod_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, locale_t _Nonnull __l) {
return strtod(__s, __end_ptr);
}
-static __inline float strtof_l(const char* __s, char** __end_ptr, locale_t __l) {
+static __inline float strtof_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, locale_t _Nonnull __l) {
return strtof(__s, __end_ptr);
}
-static __inline long strtol_l(const char* __s, char** __end_ptr, int __base, locale_t __l) {
+static __inline long strtol_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, int __base, locale_t _Nonnull __l) {
return strtol(__s, __end_ptr, __base);
}
diff --git a/libc/include/android/set_abort_message.h b/libc/include/android/set_abort_message.h
index 5d8d8ee..2be01a9 100644
--- a/libc/include/android/set_abort_message.h
+++ b/libc/include/android/set_abort_message.h
@@ -46,6 +46,6 @@
*
* Available since API level 21.
*/
-void android_set_abort_message(const char* __msg) __INTRODUCED_IN(21);
+void android_set_abort_message(const char* _Nullable __msg) __INTRODUCED_IN(21);
__END_DECLS
diff --git a/libc/include/pthread.h b/libc/include/pthread.h
index fd1ebc3..98695eb 100644
--- a/libc/include/pthread.h
+++ b/libc/include/pthread.h
@@ -94,41 +94,41 @@
#define PTHREAD_SCOPE_SYSTEM 0
#define PTHREAD_SCOPE_PROCESS 1
-int pthread_atfork(void (*__prepare)(void), void (*__parent)(void), void (*__child)(void));
+int pthread_atfork(void (* _Nullable __prepare)(void), void (* _Nullable __parent)(void), void (* _Nullable __child)(void));
-int pthread_attr_destroy(pthread_attr_t* __attr);
-int pthread_attr_getdetachstate(const pthread_attr_t* __attr, int* __state);
-int pthread_attr_getguardsize(const pthread_attr_t* __attr, size_t* __size);
-int pthread_attr_getinheritsched(const pthread_attr_t* __attr, int* __flag) __INTRODUCED_IN(28);
-int pthread_attr_getschedparam(const pthread_attr_t* __attr, struct sched_param* __param);
-int pthread_attr_getschedpolicy(const pthread_attr_t* __attr, int* __policy);
-int pthread_attr_getscope(const pthread_attr_t* __attr, int* __scope);
-int pthread_attr_getstack(const pthread_attr_t* __attr, void** __addr, size_t* __size);
-int pthread_attr_getstacksize(const pthread_attr_t* __attr, size_t* __size);
-int pthread_attr_init(pthread_attr_t* __attr);
-int pthread_attr_setdetachstate(pthread_attr_t* __attr, int __state);
-int pthread_attr_setguardsize(pthread_attr_t* __attr, size_t __size);
-int pthread_attr_setinheritsched(pthread_attr_t* __attr, int __flag) __INTRODUCED_IN(28);
-int pthread_attr_setschedparam(pthread_attr_t* __attr, const struct sched_param* __param);
-int pthread_attr_setschedpolicy(pthread_attr_t* __attr, int __policy);
-int pthread_attr_setscope(pthread_attr_t* __attr, int __scope);
-int pthread_attr_setstack(pthread_attr_t* __attr, void* __addr, size_t __size);
-int pthread_attr_setstacksize(pthread_attr_t* __addr, size_t __size);
+int pthread_attr_destroy(pthread_attr_t* _Nonnull __attr);
+int pthread_attr_getdetachstate(const pthread_attr_t* _Nonnull __attr, int* _Nonnull __state);
+int pthread_attr_getguardsize(const pthread_attr_t* _Nonnull __attr, size_t* _Nonnull __size);
+int pthread_attr_getinheritsched(const pthread_attr_t* _Nonnull __attr, int* _Nonnull __flag) __INTRODUCED_IN(28);
+int pthread_attr_getschedparam(const pthread_attr_t* _Nonnull __attr, struct sched_param* _Nonnull __param);
+int pthread_attr_getschedpolicy(const pthread_attr_t* _Nonnull __attr, int* _Nonnull __policy);
+int pthread_attr_getscope(const pthread_attr_t* _Nonnull __attr, int* _Nonnull __scope);
+int pthread_attr_getstack(const pthread_attr_t* _Nonnull __attr, void* _Nullable * _Nonnull __addr, size_t* _Nonnull __size);
+int pthread_attr_getstacksize(const pthread_attr_t* _Nonnull __attr, size_t* _Nonnull __size);
+int pthread_attr_init(pthread_attr_t* _Nonnull __attr);
+int pthread_attr_setdetachstate(pthread_attr_t* _Nonnull __attr, int __state);
+int pthread_attr_setguardsize(pthread_attr_t* _Nonnull __attr, size_t __size);
+int pthread_attr_setinheritsched(pthread_attr_t* _Nonnull __attr, int __flag) __INTRODUCED_IN(28);
+int pthread_attr_setschedparam(pthread_attr_t* _Nonnull __attr, const struct sched_param* _Nonnull __param);
+int pthread_attr_setschedpolicy(pthread_attr_t* _Nonnull __attr, int __policy);
+int pthread_attr_setscope(pthread_attr_t* _Nonnull __attr, int __scope);
+int pthread_attr_setstack(pthread_attr_t* _Nonnull __attr, void* _Nonnull __addr, size_t __size);
+int pthread_attr_setstacksize(pthread_attr_t* _Nonnull __addr, size_t __size);
-int pthread_condattr_destroy(pthread_condattr_t* __attr);
-int pthread_condattr_getclock(const pthread_condattr_t* __attr, clockid_t* __clock) __INTRODUCED_IN(21);
-int pthread_condattr_getpshared(const pthread_condattr_t* __attr, int* __shared);
-int pthread_condattr_init(pthread_condattr_t* __attr);
-int pthread_condattr_setclock(pthread_condattr_t* __attr, clockid_t __clock) __INTRODUCED_IN(21);
-int pthread_condattr_setpshared(pthread_condattr_t* __attr, int __shared);
+int pthread_condattr_destroy(pthread_condattr_t* _Nonnull __attr);
+int pthread_condattr_getclock(const pthread_condattr_t* _Nonnull __attr, clockid_t* _Nonnull __clock) __INTRODUCED_IN(21);
+int pthread_condattr_getpshared(const pthread_condattr_t* _Nonnull __attr, int* _Nonnull __shared);
+int pthread_condattr_init(pthread_condattr_t* _Nonnull __attr);
+int pthread_condattr_setclock(pthread_condattr_t* _Nonnull __attr, clockid_t __clock) __INTRODUCED_IN(21);
+int pthread_condattr_setpshared(pthread_condattr_t* _Nonnull __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);
-int pthread_cond_timedwait(pthread_cond_t* __cond, pthread_mutex_t* __mutex, const struct timespec* __timeout);
+int pthread_cond_broadcast(pthread_cond_t* _Nonnull __cond);
+int pthread_cond_clockwait(pthread_cond_t* _Nonnull __cond, pthread_mutex_t* _Nonnull __mutex, clockid_t __clock,
+ const struct timespec* _Nullable __timeout) __INTRODUCED_IN(30);
+int pthread_cond_destroy(pthread_cond_t* _Nonnull __cond);
+int pthread_cond_init(pthread_cond_t* _Nonnull __cond, const pthread_condattr_t* _Nullable __attr);
+int pthread_cond_signal(pthread_cond_t* _Nonnull __cond);
+int pthread_cond_timedwait(pthread_cond_t* _Nonnull __cond, pthread_mutex_t* _Nonnull __mutex, const struct timespec* _Nullable __timeout);
/*
* Condition variables use CLOCK_REALTIME by default for their timeouts, however that is
* typically inappropriate, since that clock can change dramatically, causing the timeout to
@@ -139,9 +139,9 @@
* 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);
-int pthread_cond_wait(pthread_cond_t* __cond, pthread_mutex_t* __mutex);
+int pthread_cond_timedwait_monotonic_np(pthread_cond_t* _Nonnull __cond, pthread_mutex_t* _Nonnull __mutex,
+ const struct timespec* _Nullable __timeout) __INTRODUCED_IN_64(28);
+int pthread_cond_wait(pthread_cond_t* _Nonnull __cond, pthread_mutex_t* _Nonnull __mutex);
#if defined(__clang__)
/*
@@ -153,44 +153,44 @@
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wbuiltin-requires-header"
#endif
-int pthread_create(pthread_t* __pthread_ptr, pthread_attr_t const* __attr, void* (*__start_routine)(void*), void*);
+int pthread_create(pthread_t* _Nonnull __pthread_ptr, pthread_attr_t const* _Nullable __attr, void* _Nonnull (* _Nonnull __start_routine)(void* _Nonnull), void* _Nullable);
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
int pthread_detach(pthread_t __pthread);
-void pthread_exit(void* __return_value) __noreturn;
+void pthread_exit(void* _Nullable __return_value) __noreturn;
int pthread_equal(pthread_t __lhs, pthread_t __rhs);
-int pthread_getattr_np(pthread_t __pthread, pthread_attr_t* __attr);
+int pthread_getattr_np(pthread_t __pthread, pthread_attr_t* _Nonnull __attr);
-int pthread_getcpuclockid(pthread_t __pthread, clockid_t* __clock);
+int pthread_getcpuclockid(pthread_t __pthread, clockid_t* _Nonnull __clock);
-void* pthread_getspecific(pthread_key_t __key);
+void* _Nullable pthread_getspecific(pthread_key_t __key);
pid_t pthread_gettid_np(pthread_t __pthread) __INTRODUCED_IN(21);
-int pthread_join(pthread_t __pthread, void** __return_value_ptr);
+int pthread_join(pthread_t __pthread, void* _Nullable * _Nullable __return_value_ptr);
-int pthread_key_create(pthread_key_t* __key_ptr, void (*__key_destructor)(void*));
+int pthread_key_create(pthread_key_t* _Nonnull __key_ptr, void (* _Nullable __key_destructor)(void* _Nullable));
int pthread_key_delete(pthread_key_t __key);
-int pthread_mutexattr_destroy(pthread_mutexattr_t* __attr);
-int pthread_mutexattr_getpshared(const pthread_mutexattr_t* __attr, int* __shared);
-int pthread_mutexattr_gettype(const pthread_mutexattr_t* __attr, int* __type);
-int pthread_mutexattr_getprotocol(const pthread_mutexattr_t* __attr, int* __protocol) __INTRODUCED_IN(28);
-int pthread_mutexattr_init(pthread_mutexattr_t* __attr);
-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_mutexattr_destroy(pthread_mutexattr_t* _Nonnull __attr);
+int pthread_mutexattr_getpshared(const pthread_mutexattr_t* _Nonnull __attr, int* _Nonnull __shared);
+int pthread_mutexattr_gettype(const pthread_mutexattr_t* _Nonnull __attr, int* _Nonnull __type);
+int pthread_mutexattr_getprotocol(const pthread_mutexattr_t* _Nonnull __attr, int* _Nonnull __protocol) __INTRODUCED_IN(28);
+int pthread_mutexattr_init(pthread_mutexattr_t* _Nonnull __attr);
+int pthread_mutexattr_setpshared(pthread_mutexattr_t* _Nonnull __attr, int __shared);
+int pthread_mutexattr_settype(pthread_mutexattr_t* _Nonnull __attr, int __type);
+int pthread_mutexattr_setprotocol(pthread_mutexattr_t* _Nonnull __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);
-int pthread_mutex_timedlock(pthread_mutex_t* __mutex, const struct timespec* __timeout)
+int pthread_mutex_clocklock(pthread_mutex_t* _Nonnull __mutex, clockid_t __clock,
+ const struct timespec* _Nullable __abstime) __INTRODUCED_IN(30);
+int pthread_mutex_destroy(pthread_mutex_t* _Nonnull __mutex);
+int pthread_mutex_init(pthread_mutex_t* _Nonnull __mutex, const pthread_mutexattr_t* _Nullable __attr);
+int pthread_mutex_lock(pthread_mutex_t* _Nonnull __mutex);
+int pthread_mutex_timedlock(pthread_mutex_t* _Nonnull __mutex, const struct timespec* _Nullable __timeout)
__INTRODUCED_IN(21);
/*
@@ -202,69 +202,69 @@
* 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)
+int pthread_mutex_timedlock_monotonic_np(pthread_mutex_t* _Nonnull __mutex, const struct timespec* _Nullable __timeout)
__INTRODUCED_IN(28);
-int pthread_mutex_trylock(pthread_mutex_t* __mutex);
-int pthread_mutex_unlock(pthread_mutex_t* __mutex);
+int pthread_mutex_trylock(pthread_mutex_t* _Nonnull __mutex);
+int pthread_mutex_unlock(pthread_mutex_t* _Nonnull __mutex);
-int pthread_once(pthread_once_t* __once, void (*__init_routine)(void));
+int pthread_once(pthread_once_t* _Nonnull __once, void (* _Nonnull __init_routine)(void));
-int pthread_rwlockattr_init(pthread_rwlockattr_t* __attr);
-int pthread_rwlockattr_destroy(pthread_rwlockattr_t* __attr);
-int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t* __attr, int* __shared);
-int pthread_rwlockattr_setpshared(pthread_rwlockattr_t* __attr, int __shared);
-int pthread_rwlockattr_getkind_np(const pthread_rwlockattr_t* __attr, int* __kind)
+int pthread_rwlockattr_init(pthread_rwlockattr_t* _Nonnull __attr);
+int pthread_rwlockattr_destroy(pthread_rwlockattr_t* _Nonnull __attr);
+int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t* _Nonnull __attr, int* _Nonnull __shared);
+int pthread_rwlockattr_setpshared(pthread_rwlockattr_t* _Nonnull __attr, int __shared);
+int pthread_rwlockattr_getkind_np(const pthread_rwlockattr_t* _Nonnull __attr, int* _Nonnull __kind)
__INTRODUCED_IN(23);
-int pthread_rwlockattr_setkind_np(pthread_rwlockattr_t* __attr, int __kind) __INTRODUCED_IN(23);
+int pthread_rwlockattr_setkind_np(pthread_rwlockattr_t* _Nonnull __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);
-int pthread_rwlock_timedrdlock(pthread_rwlock_t* __rwlock, const struct timespec* __timeout);
+int pthread_rwlock_clockrdlock(pthread_rwlock_t* _Nonnull __rwlock, clockid_t __clock,
+ const struct timespec* _Nullable __timeout) __INTRODUCED_IN(30);
+int pthread_rwlock_clockwrlock(pthread_rwlock_t* _Nonnull __rwlock, clockid_t __clock,
+ const struct timespec* _Nullable __timeout) __INTRODUCED_IN(30);
+int pthread_rwlock_destroy(pthread_rwlock_t* _Nonnull __rwlock);
+int pthread_rwlock_init(pthread_rwlock_t* _Nonnull __rwlock, const pthread_rwlockattr_t* _Nullable __attr);
+int pthread_rwlock_rdlock(pthread_rwlock_t* _Nonnull __rwlock);
+int pthread_rwlock_timedrdlock(pthread_rwlock_t* _Nonnull __rwlock, const struct timespec* _Nullable __timeout);
/* See the comment on pthread_mutex_timedlock_monotonic_np for usage of this function. */
-int pthread_rwlock_timedrdlock_monotonic_np(pthread_rwlock_t* __rwlock,
- const struct timespec* __timeout) __INTRODUCED_IN(28);
-int pthread_rwlock_timedwrlock(pthread_rwlock_t* __rwlock, const struct timespec* __timeout);
+int pthread_rwlock_timedrdlock_monotonic_np(pthread_rwlock_t* _Nonnull __rwlock,
+ const struct timespec* _Nullable __timeout) __INTRODUCED_IN(28);
+int pthread_rwlock_timedwrlock(pthread_rwlock_t* _Nonnull __rwlock, const struct timespec* _Nullable __timeout);
/* See the comment on pthread_mutex_timedlock_monotonic_np for usage of this function. */
-int pthread_rwlock_timedwrlock_monotonic_np(pthread_rwlock_t* __rwlock,
- const struct timespec* __timeout) __INTRODUCED_IN(28);
-int pthread_rwlock_tryrdlock(pthread_rwlock_t* __rwlock);
-int pthread_rwlock_trywrlock(pthread_rwlock_t* __rwlock);
-int pthread_rwlock_unlock(pthread_rwlock_t* __rwlock);
-int pthread_rwlock_wrlock(pthread_rwlock_t* __rwlock);
+int pthread_rwlock_timedwrlock_monotonic_np(pthread_rwlock_t* _Nonnull __rwlock,
+ const struct timespec* _Nullable __timeout) __INTRODUCED_IN(28);
+int pthread_rwlock_tryrdlock(pthread_rwlock_t* _Nonnull __rwlock);
+int pthread_rwlock_trywrlock(pthread_rwlock_t* _Nonnull __rwlock);
+int pthread_rwlock_unlock(pthread_rwlock_t* _Nonnull __rwlock);
+int pthread_rwlock_wrlock(pthread_rwlock_t* _Nonnull __rwlock);
#if __ANDROID_API__ >= 24
-int pthread_barrierattr_init(pthread_barrierattr_t* __attr) __INTRODUCED_IN(24);
-int pthread_barrierattr_destroy(pthread_barrierattr_t* __attr) __INTRODUCED_IN(24);
-int pthread_barrierattr_getpshared(const pthread_barrierattr_t* __attr, int* __shared) __INTRODUCED_IN(24);
-int pthread_barrierattr_setpshared(pthread_barrierattr_t* __attr, int __shared) __INTRODUCED_IN(24);
+int pthread_barrierattr_init(pthread_barrierattr_t* _Nonnull __attr) __INTRODUCED_IN(24);
+int pthread_barrierattr_destroy(pthread_barrierattr_t* _Nonnull __attr) __INTRODUCED_IN(24);
+int pthread_barrierattr_getpshared(const pthread_barrierattr_t* _Nonnull __attr, int* _Nonnull __shared) __INTRODUCED_IN(24);
+int pthread_barrierattr_setpshared(pthread_barrierattr_t* _Nonnull __attr, int __shared) __INTRODUCED_IN(24);
#endif
#if __ANDROID_API__ >= 24
-int pthread_barrier_init(pthread_barrier_t* __barrier, const pthread_barrierattr_t* __attr, unsigned __count) __INTRODUCED_IN(24);
-int pthread_barrier_destroy(pthread_barrier_t* __barrier) __INTRODUCED_IN(24);
-int pthread_barrier_wait(pthread_barrier_t* __barrier) __INTRODUCED_IN(24);
+int pthread_barrier_init(pthread_barrier_t* _Nonnull __barrier, const pthread_barrierattr_t* _Nullable __attr, unsigned __count) __INTRODUCED_IN(24);
+int pthread_barrier_destroy(pthread_barrier_t* _Nonnull __barrier) __INTRODUCED_IN(24);
+int pthread_barrier_wait(pthread_barrier_t* _Nonnull __barrier) __INTRODUCED_IN(24);
#endif
#if __ANDROID_API__ >= 24
-int pthread_spin_destroy(pthread_spinlock_t* __spinlock) __INTRODUCED_IN(24);
-int pthread_spin_init(pthread_spinlock_t* __spinlock, int __shared) __INTRODUCED_IN(24);
-int pthread_spin_lock(pthread_spinlock_t* __spinlock) __INTRODUCED_IN(24);
-int pthread_spin_trylock(pthread_spinlock_t* __spinlock) __INTRODUCED_IN(24);
-int pthread_spin_unlock(pthread_spinlock_t* __spinlock) __INTRODUCED_IN(24);
+int pthread_spin_destroy(pthread_spinlock_t* _Nonnull __spinlock) __INTRODUCED_IN(24);
+int pthread_spin_init(pthread_spinlock_t* _Nonnull __spinlock, int __shared) __INTRODUCED_IN(24);
+int pthread_spin_lock(pthread_spinlock_t* _Nonnull __spinlock) __INTRODUCED_IN(24);
+int pthread_spin_trylock(pthread_spinlock_t* _Nonnull __spinlock) __INTRODUCED_IN(24);
+int pthread_spin_unlock(pthread_spinlock_t* _Nonnull __spinlock) __INTRODUCED_IN(24);
#endif
pthread_t pthread_self(void) __attribute_const__;
#if defined(__USE_GNU)
-int pthread_getname_np(pthread_t __pthread, char* __buf, size_t __n) __INTRODUCED_IN(26);
+int pthread_getname_np(pthread_t __pthread, char* _Nonnull __buf, size_t __n) __INTRODUCED_IN(26);
#endif
/* TODO: this should be __USE_GNU too. */
-int pthread_setname_np(pthread_t __pthread, const char* __name);
+int pthread_setname_np(pthread_t __pthread, const char* _Nonnull __name);
/**
* [pthread_setschedparam(3)](https://man7.org/linux/man-pages/man3/pthread_setschedparam.3.html)
@@ -277,7 +277,7 @@
*
* Returns 0 on success and returns an error number on failure.
*/
-int pthread_setschedparam(pthread_t __pthread, int __policy, const struct sched_param* __param);
+int pthread_setschedparam(pthread_t __pthread, int __policy, const struct sched_param* _Nonnull __param);
/**
* [pthread_getschedparam(3)](https://man7.org/linux/man-pages/man3/pthread_getschedparam.3.html)
@@ -285,7 +285,7 @@
*
* Returns 0 on success and returns an error number on failure.
*/
-int pthread_getschedparam(pthread_t __pthread, int* __policy, struct sched_param* __param);
+int pthread_getschedparam(pthread_t __pthread, int* _Nonnull __policy, struct sched_param* _Nonnull __param);
/**
* [pthread_setschedprio(3)](https://man7.org/linux/man-pages/man3/pthread_setschedprio.3.html)
@@ -302,18 +302,18 @@
*/
int pthread_setschedprio(pthread_t __pthread, int __priority) __INTRODUCED_IN(28);
-int pthread_setspecific(pthread_key_t __key, const void* __value);
+int pthread_setspecific(pthread_key_t __key, const void* _Nullable __value);
-typedef void (*__pthread_cleanup_func_t)(void*);
+typedef void (* _Nullable __pthread_cleanup_func_t)(void* _Nullable);
typedef struct __pthread_cleanup_t {
- struct __pthread_cleanup_t* __cleanup_prev;
- __pthread_cleanup_func_t __cleanup_routine;
- void* __cleanup_arg;
+ struct __pthread_cleanup_t* _Nullable __cleanup_prev;
+ __pthread_cleanup_func_t _Nullable __cleanup_routine;
+ void* _Nullable __cleanup_arg;
} __pthread_cleanup_t;
-void __pthread_cleanup_push(__pthread_cleanup_t* c, __pthread_cleanup_func_t, void*);
-void __pthread_cleanup_pop(__pthread_cleanup_t*, int);
+void __pthread_cleanup_push(__pthread_cleanup_t* _Nonnull c, __pthread_cleanup_func_t _Nullable, void* _Nullable);
+void __pthread_cleanup_pop(__pthread_cleanup_t* _Nonnull, int);
/* Believe or not, the definitions of pthread_cleanup_push and
* pthread_cleanup_pop below are correct. Posix states that these
diff --git a/libc/include/semaphore.h b/libc/include/semaphore.h
index 5d66f7e..6ad9ea3 100644
--- a/libc/include/semaphore.h
+++ b/libc/include/semaphore.h
@@ -45,12 +45,12 @@
#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);
+int sem_clockwait(sem_t* _Nonnull __sem, clockid_t __clock, const struct timespec* _Nonnull __ts) __INTRODUCED_IN(30);
+int sem_destroy(sem_t* _Nonnull __sem);
+int sem_getvalue(sem_t* _Nonnull __sem, int* _Nonnull __value);
+int sem_init(sem_t* _Nonnull __sem, int __shared, unsigned int __value);
+int sem_post(sem_t* _Nonnull __sem);
+int sem_timedwait(sem_t* _Nonnull __sem, const struct timespec* _Nonnull __ts);
/*
* 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
@@ -59,14 +59,14 @@
* 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);
-int sem_wait(sem_t* __sem);
+int sem_timedwait_monotonic_np(sem_t* _Nonnull __sem, const struct timespec* _Nonnull __ts) __INTRODUCED_IN(28);
+int sem_trywait(sem_t* _Nonnull __sem);
+int sem_wait(sem_t* _Nonnull __sem);
/* These aren't actually implemented. */
-sem_t* sem_open(const char* __name, int _flags, ...);
-int sem_close(sem_t* __sem);
-int sem_unlink(const char* __name);
+sem_t* _Nullable sem_open(const char* _Nonnull __name, int _flags, ...);
+int sem_close(sem_t* _Nonnull __sem);
+int sem_unlink(const char* _Nonnull __name);
__END_DECLS
diff --git a/libc/include/setjmp.h b/libc/include/setjmp.h
index a3de9c7..6d047ae 100644
--- a/libc/include/setjmp.h
+++ b/libc/include/setjmp.h
@@ -47,14 +47,33 @@
#include <sys/cdefs.h>
#if defined(__aarch64__)
+/**
+ * The size in words of an arm64 jmp_buf. Room for callee-saved registers,
+ * including floating point, stack pointer and program counter, various
+ * internal implementation details, and leaving some free space.
+ *
+ * Coincidentally matches OpenBSD, though they also save/restore the
+ * floating point status register too.
+ */
#define _JBLEN 32
#elif defined(__arm__)
+/** The size in words of an arm32 jmp_buf. Inherited from OpenBSD. */
#define _JBLEN 64
#elif defined(__i386__)
+/** The size in words of an x86 jmp_buf. Inherited from OpenBSD. */
#define _JBLEN 10
#elif defined(__riscv)
-#define _JBLEN 29
+/**
+ * The size in words of a riscv64 jmp_buf. Room for callee-saved registers,
+ * including floating point, stack pointer and program counter, various
+ * internal implementation details, and leaving some free space.
+ *
+ * Coincidentally matches OpenBSD, though they also save/restore the
+ * floating point status register too.
+ */
+#define _JBLEN 32
#elif defined(__x86_64__)
+/** The size in words of an x86-64 jmp_buf. Inherited from OpenBSD. */
#define _JBLEN 11
#endif
diff --git a/libc/include/sys/capability.h b/libc/include/sys/capability.h
index 4cb698f..b43bbf0 100644
--- a/libc/include/sys/capability.h
+++ b/libc/include/sys/capability.h
@@ -44,7 +44,7 @@
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
*/
-int capget(cap_user_header_t __hdr_ptr, cap_user_data_t __data_ptr);
+int capget(cap_user_header_t _Nonnull __hdr_ptr, cap_user_data_t _Nullable __data_ptr);
/**
* [capset(2)](http://man7.org/linux/man-pages/man2/capset.2.html) sets the calling
@@ -52,6 +52,6 @@
*
* Returns 0 on success, and returns -1 and sets `errno` on failure.
*/
-int capset(cap_user_header_t __hdr_ptr, const cap_user_data_t __data_ptr);
+int capset(cap_user_header_t _Nonnull __hdr_ptr, const cap_user_data_t _Nullable __data_ptr);
__END_DECLS
diff --git a/libc/include/sys/ipc.h b/libc/include/sys/ipc.h
index c81ec1a..2e2b8cf 100644
--- a/libc/include/sys/ipc.h
+++ b/libc/include/sys/ipc.h
@@ -52,6 +52,6 @@
*
* Returns a key on success, and returns -1 and sets `errno` on failure.
*/
-key_t ftok(const char* __path, int __id);
+key_t ftok(const char* _Nonnull __path, int __id);
__END_DECLS
diff --git a/libc/include/sys/random.h b/libc/include/sys/random.h
index be52bd9..0251176 100644
--- a/libc/include/sys/random.h
+++ b/libc/include/sys/random.h
@@ -50,7 +50,7 @@
*
* See also arc4random_buf() which is available in all API levels.
*/
-int getentropy(void* __buffer, size_t __buffer_size) __wur __INTRODUCED_IN(28);
+int getentropy(void* _Nonnull __buffer, size_t __buffer_size) __wur __INTRODUCED_IN(28);
/**
* [getrandom(2)](http://man7.org/linux/man-pages/man2/getrandom.2.html) fills the given buffer
@@ -62,6 +62,6 @@
*
* See also arc4random_buf() which is available in all API levels.
*/
-ssize_t getrandom(void* __buffer, size_t __buffer_size, unsigned int __flags) __wur __INTRODUCED_IN(28);
+ssize_t getrandom(void* _Nonnull __buffer, size_t __buffer_size, unsigned int __flags) __wur __INTRODUCED_IN(28);
__END_DECLS
diff --git a/libc/include/sys/sendfile.h b/libc/include/sys/sendfile.h
index 60bbde8..4b00d5d 100644
--- a/libc/include/sys/sendfile.h
+++ b/libc/include/sys/sendfile.h
@@ -40,7 +40,7 @@
/* See https://android.googlesource.com/platform/bionic/+/master/docs/32-bit-abi.md */
#if defined(__USE_FILE_OFFSET64)
-ssize_t sendfile(int __out_fd, int __in_fd, off_t* __offset, size_t __count) __RENAME(sendfile64) __INTRODUCED_IN(21);
+ssize_t sendfile(int __out_fd, int __in_fd, off_t* _Nullable __offset, size_t __count) __RENAME(sendfile64) __INTRODUCED_IN(21);
#else
/**
* [sendfile(2)](http://man7.org/linux/man-pages/man2/sendfile.2.html) copies data directly
@@ -50,13 +50,13 @@
*
* Available since API level 21.
*/
-ssize_t sendfile(int __out_fd, int __in_fd, off_t* __offset, size_t __count);
+ssize_t sendfile(int __out_fd, int __in_fd, off_t* _Nullable __offset, size_t __count);
#endif
/**
* Like sendfile() but allows using a 64-bit offset
* even from a 32-bit process without `__FILE_OFFSET_BITS=64`.
*/
-ssize_t sendfile64(int __out_fd, int __in_fd, off64_t* __offset, size_t __count) __INTRODUCED_IN(21);
+ssize_t sendfile64(int __out_fd, int __in_fd, off64_t* _Nullable __offset, size_t __count) __INTRODUCED_IN(21);
__END_DECLS
diff --git a/libdl/Android.bp b/libdl/Android.bp
index 4cdec44..fde3dfc 100644
--- a/libdl/Android.bp
+++ b/libdl/Android.bp
@@ -244,7 +244,7 @@
genrule {
name: "libdl.arm.map",
- out: ["libdl.arm.map"],
+ out: ["libdl.arm.map.txt"],
srcs: ["libdl.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) arm $(in) $(out)",
@@ -252,7 +252,7 @@
genrule {
name: "libdl.arm64.map",
- out: ["libdl.arm64.map"],
+ out: ["libdl.arm64.map.txt"],
srcs: ["libdl.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) arm64 $(in) $(out)",
@@ -260,7 +260,7 @@
genrule {
name: "libdl.riscv64.map",
- out: ["libdl.riscv64.map"],
+ out: ["libdl.riscv64.map.txt"],
srcs: ["libdl.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) riscv64 $(in) $(out)",
@@ -268,7 +268,7 @@
genrule {
name: "libdl.x86.map",
- out: ["libdl.x86.map"],
+ out: ["libdl.x86.map.txt"],
srcs: ["libdl.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) x86 $(in) $(out)",
@@ -276,7 +276,7 @@
genrule {
name: "libdl.x86_64.map",
- out: ["libdl.x86_64.map"],
+ out: ["libdl.x86_64.map.txt"],
srcs: ["libdl.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) x86_64 $(in) $(out)",
diff --git a/libm/Android.bp b/libm/Android.bp
index 4c34fb6..13fbf9a 100644
--- a/libm/Android.bp
+++ b/libm/Android.bp
@@ -473,7 +473,7 @@
genrule {
name: "libm.arm.map",
- out: ["libm.arm.map"],
+ out: ["libm.arm.map.txt"],
srcs: ["libm.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) arm $(in) $(out)",
@@ -481,7 +481,7 @@
genrule {
name: "libm.arm64.map",
- out: ["libm.arm64.map"],
+ out: ["libm.arm64.map.txt"],
srcs: ["libm.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) arm64 $(in) $(out)",
@@ -489,7 +489,7 @@
genrule {
name: "libm.riscv64.map",
- out: ["libm.riscv64.map"],
+ out: ["libm.riscv64.map.txt"],
srcs: ["libm.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) riscv64 $(in) $(out)",
@@ -497,7 +497,7 @@
genrule {
name: "libm.x86.map",
- out: ["libm.x86.map"],
+ out: ["libm.x86.map.txt"],
srcs: ["libm.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) x86 $(in) $(out)",
@@ -505,7 +505,7 @@
genrule {
name: "libm.x86_64.map",
- out: ["libm.x86_64.map"],
+ out: ["libm.x86_64.map.txt"],
srcs: ["libm.map.txt"],
tools: ["generate-version-script"],
cmd: "$(location generate-version-script) x86_64 $(in) $(out)",
diff --git a/tests/Android.bp b/tests/Android.bp
index cd20cd7..1be1ec3 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -541,6 +541,10 @@
// unsupported relocation type 37
"ifunc_test.cpp",
+
+ // musl #defines utmp to utmpx, causing a collision with
+ // utmpx_test.cpp
+ "utmp_test.cpp",
],
},
},
diff --git a/tests/semaphore_test.cpp b/tests/semaphore_test.cpp
index f3f6020..6f8797f 100644
--- a/tests/semaphore_test.cpp
+++ b/tests/semaphore_test.cpp
@@ -165,8 +165,10 @@
TEST_F(semaphore_DeathTest, sem_timedwait_null_timeout) {
sem_t s;
ASSERT_EQ(0, sem_init(&s, 0, 0));
-
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
ASSERT_EXIT(sem_timedwait(&s, nullptr), testing::KilledBySignal(SIGSEGV), "");
+#pragma clang diagnostic pop
}
TEST(semaphore, sem_getvalue) {
diff --git a/tests/sys_random_test.cpp b/tests/sys_random_test.cpp
index 2e2665b..e0cbf78 100644
--- a/tests/sys_random_test.cpp
+++ b/tests/sys_random_test.cpp
@@ -48,6 +48,8 @@
}
TEST(sys_random, getentropy_EFAULT) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
#if defined(HAVE_SYS_RANDOM)
errno = 0;
ASSERT_EQ(-1, getentropy(nullptr, 1));
@@ -55,6 +57,7 @@
#else
GTEST_SKIP() << "<sys/random.h> not available";
#endif
+#pragma clang diagnostic pop
}
TEST(sys_random, getentropy_EIO) {
@@ -84,6 +87,8 @@
}
TEST(sys_random, getrandom_EFAULT) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
#if defined(HAVE_SYS_RANDOM)
errno = 0;
ASSERT_EQ(-1, getrandom(nullptr, 256, 0));
@@ -91,6 +96,7 @@
#else
GTEST_SKIP() << "<sys/random.h> not available";
#endif
+#pragma clang diagnostic pop
}
TEST(sys_random, getrandom_EINVAL) {