Merge "Add test for mallinfo."
diff --git a/libc/Android.bp b/libc/Android.bp
index 6209374..c08df9d 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -551,13 +551,9 @@
arm: {
exclude_srcs: [
"upstream-openbsd/lib/libc/string/strcpy.c",
+ "upstream-openbsd/lib/libc/string/stpcpy.c",
+ "upstream-openbsd/lib/libc/string/strcat.c",
],
- neon: {
- exclude_srcs: [
- "upstream-openbsd/lib/libc/string/stpcpy.c",
- "upstream-openbsd/lib/libc/string/strcat.c",
- ],
- },
},
arm64: {
exclude_srcs: [
@@ -849,6 +845,8 @@
"arch-arm/generic/bionic/memcmp.S",
"arch-arm/generic/bionic/memmove.S",
"arch-arm/generic/bionic/memset.S",
+ "arch-arm/generic/bionic/stpcpy.c",
+ "arch-arm/generic/bionic/strcat.c",
"arch-arm/generic/bionic/strcmp.S",
"arch-arm/generic/bionic/strcpy.S",
"arch-arm/generic/bionic/strlen.c",
@@ -862,162 +860,44 @@
"arch-arm/bionic/setjmp.S",
"arch-arm/bionic/syscall.S",
"arch-arm/bionic/vfork.S",
+
+ "arch-arm/cortex-a15/bionic/memcpy.S",
+ "arch-arm/cortex-a15/bionic/memmove.S",
+ "arch-arm/cortex-a15/bionic/memset.S",
+ "arch-arm/cortex-a15/bionic/stpcpy.S",
+ "arch-arm/cortex-a15/bionic/strcat.S",
+ "arch-arm/cortex-a15/bionic/strcmp.S",
+ "arch-arm/cortex-a15/bionic/strcpy.S",
+ "arch-arm/cortex-a15/bionic/strlen.S",
+
+ "arch-arm/cortex-a7/bionic/memcpy.S",
+ "arch-arm/cortex-a7/bionic/memmove.S",
+ "arch-arm/cortex-a7/bionic/memset.S",
+
+ "arch-arm/cortex-a9/bionic/memcpy.S",
+ "arch-arm/cortex-a9/bionic/memmove.S",
+ "arch-arm/cortex-a9/bionic/memset.S",
+ "arch-arm/cortex-a9/bionic/stpcpy.S",
+ "arch-arm/cortex-a9/bionic/strcat.S",
+ "arch-arm/cortex-a9/bionic/strcmp.S",
+ "arch-arm/cortex-a9/bionic/strcpy.S",
+ "arch-arm/cortex-a9/bionic/strlen.S",
+
+ "arch-arm/krait/bionic/memcpy.S",
+ "arch-arm/krait/bionic/memmove.S",
+ "arch-arm/krait/bionic/memset.S",
+ "arch-arm/krait/bionic/strcmp.S",
+
+ "arch-arm/cortex-a53/bionic/memcpy.S",
+ "arch-arm/cortex-a53/bionic/memmove.S",
+
+ "arch-arm/denver/bionic/memcpy.S",
+ "arch-arm/denver/bionic/memmove.S",
+ "arch-arm/denver/bionic/memset.S",
+
+ "arch-arm/kryo/bionic/memcpy.S",
+ "arch-arm/kryo/bionic/memmove.S",
],
- cortex_a7: {
- srcs: [
- "arch-arm/cortex-a7/bionic/memcpy.S",
- "arch-arm/cortex-a7/bionic/memset.S",
- ],
- exclude_srcs: [
- "arch-arm/cortex-a15/bionic/memcpy.S",
- "arch-arm/cortex-a15/bionic/memset.S",
- ],
- },
- cortex_a9: {
- srcs: [
- "arch-arm/cortex-a9/bionic/memcpy.S",
- "arch-arm/cortex-a9/bionic/memset.S",
-
- "arch-arm/cortex-a9/bionic/stpcpy.S",
- "arch-arm/cortex-a9/bionic/strcat.S",
- "arch-arm/cortex-a9/bionic/strcmp.S",
- "arch-arm/cortex-a9/bionic/strcpy.S",
- "arch-arm/cortex-a9/bionic/strlen.S",
- ],
- exclude_srcs: [
- "arch-arm/cortex-a15/bionic/memcpy.S",
- "arch-arm/cortex-a15/bionic/memset.S",
-
- "arch-arm/cortex-a15/bionic/stpcpy.S",
- "arch-arm/cortex-a15/bionic/strcat.S",
- "arch-arm/cortex-a15/bionic/strcmp.S",
- "arch-arm/cortex-a15/bionic/strcpy.S",
- "arch-arm/cortex-a15/bionic/strlen.S",
- ],
- },
- krait: {
- srcs: [
- "arch-arm/krait/bionic/memcpy.S",
- "arch-arm/krait/bionic/memset.S",
-
- "arch-arm/krait/bionic/strcmp.S",
- ],
- exclude_srcs: [
- "arch-arm/cortex-a15/bionic/memset.S",
- "arch-arm/cortex-a15/bionic/memcpy.S",
-
- "arch-arm/cortex-a15/bionic/strcmp.S",
- ],
- },
- cortex_a53: {
- srcs: [
- "arch-arm/cortex-a53/bionic/memcpy.S",
- "arch-arm/cortex-a7/bionic/memset.S",
- ],
- exclude_srcs: [
- "arch-arm/cortex-a15/bionic/memset.S",
- "arch-arm/cortex-a15/bionic/memcpy.S",
- ],
- },
- cortex_a55: {
- srcs: [
- "arch-arm/cortex-a7/bionic/memset.S",
- "arch-arm/denver/bionic/memcpy.S",
-
- "arch-arm/krait/bionic/strcmp.S",
- ],
- exclude_srcs: [
- "arch-arm/cortex-a15/bionic/memset.S",
- "arch-arm/cortex-a15/bionic/memcpy.S",
- "arch-arm/cortex-a15/bionic/strcmp.S",
- ],
- },
- cortex_a73: {
- srcs: [
- "arch-arm/cortex-a7/bionic/memset.S",
- "arch-arm/denver/bionic/memcpy.S",
-
- "arch-arm/krait/bionic/strcmp.S",
- ],
- exclude_srcs: [
- "arch-arm/cortex-a15/bionic/memset.S",
- "arch-arm/cortex-a15/bionic/memcpy.S",
- "arch-arm/cortex-a15/bionic/strcmp.S",
- ],
- },
- cortex_a75: {
- srcs: [
- "arch-arm/cortex-a7/bionic/memset.S",
- "arch-arm/denver/bionic/memcpy.S",
-
- "arch-arm/krait/bionic/strcmp.S",
- ],
- exclude_srcs: [
- "arch-arm/cortex-a15/bionic/memset.S",
- "arch-arm/cortex-a15/bionic/memcpy.S",
- "arch-arm/cortex-a15/bionic/strcmp.S",
- ],
- },
- cortex_a76: {
- srcs: [
- "arch-arm/cortex-a7/bionic/memset.S",
- "arch-arm/denver/bionic/memcpy.S",
-
- "arch-arm/krait/bionic/strcmp.S",
- ],
- exclude_srcs: [
- "arch-arm/cortex-a15/bionic/memset.S",
- "arch-arm/cortex-a15/bionic/memcpy.S",
- "arch-arm/cortex-a15/bionic/strcmp.S",
- ],
- },
- denver: {
- srcs: [
- "arch-arm/denver/bionic/memcpy.S",
- "arch-arm/denver/bionic/memset.S",
- ],
- exclude_srcs: [
- "arch-arm/cortex-a15/bionic/memset.S",
- "arch-arm/cortex-a15/bionic/memcpy.S",
- ],
- },
- kryo: {
- srcs: [
- "arch-arm/kryo/bionic/memcpy.S",
- "arch-arm/cortex-a7/bionic/memset.S",
-
- "arch-arm/krait/bionic/strcmp.S",
- ],
- exclude_srcs: [
- "arch-arm/cortex-a15/bionic/memset.S",
- "arch-arm/cortex-a15/bionic/memcpy.S",
- "arch-arm/cortex-a15/bionic/strcmp.S",
- ],
- },
- // Cores not listed above (like cortex-a8, cortex-a15) or
- // "generic" core will use the following implementation.
- neon: {
- srcs: [
- "arch-arm/cortex-a15/bionic/memcpy.S",
- "arch-arm/cortex-a15/bionic/memset.S",
-
- "arch-arm/cortex-a15/bionic/stpcpy.S",
- "arch-arm/cortex-a15/bionic/strcat.S",
- "arch-arm/cortex-a15/bionic/strcmp.S",
- "arch-arm/cortex-a15/bionic/strcpy.S",
- "arch-arm/cortex-a15/bionic/strlen.S",
-
- "arch-arm/denver/bionic/memmove.S",
- ],
- exclude_srcs: [
- "arch-arm/generic/bionic/memcpy.S",
- "arch-arm/generic/bionic/memmove.S",
- "arch-arm/generic/bionic/memset.S",
- "arch-arm/generic/bionic/strcmp.S",
- "arch-arm/generic/bionic/strcpy.S",
- "arch-arm/generic/bionic/strlen.c",
- ],
- },
},
arm64: {
srcs: [
@@ -1636,6 +1516,9 @@
x86: {
srcs: ["arch-x86/static_function_dispatch.S"],
},
+ arm: {
+ srcs: ["arch-arm/static_function_dispatch.S"],
+ },
},
whole_static_libs: [
@@ -1658,6 +1541,9 @@
x86: {
srcs: ["arch-x86/dynamic_function_dispatch.cpp"],
},
+ arm: {
+ srcs: ["arch-arm/dynamic_function_dispatch.cpp"],
+ },
},
whole_static_libs: [
diff --git a/libc/arch-arm/cortex-a15/bionic/memcpy.S b/libc/arch-arm/cortex-a15/bionic/memcpy.S
index 0bab6ee..a9dfaff 100644
--- a/libc/arch-arm/cortex-a15/bionic/memcpy.S
+++ b/libc/arch-arm/cortex-a15/bionic/memcpy.S
@@ -64,7 +64,7 @@
.arch armv7-a
// Prototype: void *memcpy (void *dst, const void *src, size_t count).
-ENTRY(__memcpy)
+ENTRY(__memcpy_a15)
pld [r1, #64]
push {r0, lr}
.cfi_def_cfa_offset 8
@@ -72,4 +72,4 @@
.cfi_rel_offset lr, 4
#include "memcpy_base.S"
-END(__memcpy)
+END(__memcpy_a15)
diff --git a/libc/include/android/legacy_get_device_api_level_inlines.h b/libc/arch-arm/cortex-a15/bionic/memmove.S
similarity index 86%
copy from libc/include/android/legacy_get_device_api_level_inlines.h
copy to libc/arch-arm/cortex-a15/bionic/memmove.S
index b60123c..2b12de0 100644
--- a/libc/include/android/legacy_get_device_api_level_inlines.h
+++ b/libc/arch-arm/cortex-a15/bionic/memmove.S
@@ -26,13 +26,7 @@
* SUCH DAMAGE.
*/
-#pragma once
+#define MEMMOVE memmove_a15
+#define MEMCPY __memcpy_a15
-#include <sys/cdefs.h>
-
-#if __ANDROID_API__ < __ANDROID_API_Q__
-
-#define __BIONIC_GET_DEVICE_API_LEVEL_INLINE static __inline
-#include <bits/get_device_api_level_inlines.h>
-
-#endif
+#include <arch-arm/denver/bionic/memmove.S>
diff --git a/libc/arch-arm/cortex-a15/bionic/memset.S b/libc/arch-arm/cortex-a15/bionic/memset.S
index 4b4388e..ead881e 100644
--- a/libc/arch-arm/cortex-a15/bionic/memset.S
+++ b/libc/arch-arm/cortex-a15/bionic/memset.S
@@ -41,7 +41,7 @@
// arch. The code generated is exactly the same.
.arch armv7-a
-ENTRY(__memset_chk)
+ENTRY(__memset_chk_a15)
cmp r2, r3
bls memset
@@ -51,9 +51,9 @@
.cfi_rel_offset lr, 0
bl __memset_chk_fail
-END(__memset_chk)
+END(__memset_chk_a15)
-ENTRY(memset)
+ENTRY(memset_a15)
stmfd sp!, {r0}
.cfi_def_cfa_offset 4
.cfi_rel_offset r0, 0
@@ -171,4 +171,4 @@
strbcs r1, [r0], #1
ldmfd sp!, {r0}
bx lr
-END(memset)
+END(memset_a15)
diff --git a/libc/arch-arm/cortex-a15/bionic/strcat.S b/libc/arch-arm/cortex-a15/bionic/strcat.S
index 157cc9f..260926a 100644
--- a/libc/arch-arm/cortex-a15/bionic/strcat.S
+++ b/libc/arch-arm/cortex-a15/bionic/strcat.S
@@ -80,7 +80,7 @@
\cmd \reg, \label
.endm // m_copy_byte
-ENTRY(strcat)
+ENTRY(strcat_a15)
// Quick check to see if src is empty.
ldrb r2, [r1]
pld [r1, #0]
@@ -572,4 +572,4 @@
.L_strcat_sub2:
sub r0, r0, #2
b .L_strcat_r0_scan_done
-END(strcat)
+END(strcat_a15)
diff --git a/libc/arch-arm/cortex-a15/bionic/strcmp.S b/libc/arch-arm/cortex-a15/bionic/strcmp.S
index d8993d5..58dbf17 100644
--- a/libc/arch-arm/cortex-a15/bionic/strcmp.S
+++ b/libc/arch-arm/cortex-a15/bionic/strcmp.S
@@ -61,7 +61,7 @@
// arch. The code generated is exactly the same.
.arch armv7-a
-ENTRY(strcmp)
+ENTRY(strcmp_a15)
/* Use LDRD whenever possible. */
/* The main thing to look out for when comparing large blocks is that
@@ -376,4 +376,4 @@
it ls
sbcls r0, r0, r0
bx lr
-END(strcmp)
+END(strcmp_a15)
diff --git a/libc/arch-arm/cortex-a15/bionic/string_copy.S b/libc/arch-arm/cortex-a15/bionic/string_copy.S
index 92d1c98..affbc3b 100644
--- a/libc/arch-arm/cortex-a15/bionic/string_copy.S
+++ b/libc/arch-arm/cortex-a15/bionic/string_copy.S
@@ -100,9 +100,9 @@
.endm // m_copy_byte
#if defined(STPCPY)
-ENTRY(stpcpy)
+ENTRY(stpcpy_a15)
#else
-ENTRY(strcpy)
+ENTRY(strcpy_a15)
#endif
// For short copies, hard-code checking the first 8 bytes since this
// new code doesn't win until after about 8 bytes.
@@ -514,7 +514,7 @@
strb r4, [r0]
m_pop
#if defined(STPCPY)
-END(stpcpy)
+END(stpcpy_a15)
#else
-END(strcpy)
+END(strcpy_a15)
#endif
diff --git a/libc/arch-arm/cortex-a15/bionic/strlen.S b/libc/arch-arm/cortex-a15/bionic/strlen.S
index 4fd6284..9c5ed29 100644
--- a/libc/arch-arm/cortex-a15/bionic/strlen.S
+++ b/libc/arch-arm/cortex-a15/bionic/strlen.S
@@ -60,7 +60,7 @@
.thumb
.thumb_func
-ENTRY(strlen)
+ENTRY(strlen_a15)
pld [r0, #0]
mov r1, r0
@@ -162,4 +162,4 @@
.L_sub2_and_return:
sub r0, r0, #2
bx lr
-END(strlen)
+END(strlen_a15)
diff --git a/libc/arch-arm/cortex-a53/bionic/memcpy.S b/libc/arch-arm/cortex-a53/bionic/memcpy.S
index 0bab6ee..ea748bd 100644
--- a/libc/arch-arm/cortex-a53/bionic/memcpy.S
+++ b/libc/arch-arm/cortex-a53/bionic/memcpy.S
@@ -64,7 +64,7 @@
.arch armv7-a
// Prototype: void *memcpy (void *dst, const void *src, size_t count).
-ENTRY(__memcpy)
+ENTRY(__memcpy_a53)
pld [r1, #64]
push {r0, lr}
.cfi_def_cfa_offset 8
@@ -72,4 +72,4 @@
.cfi_rel_offset lr, 4
#include "memcpy_base.S"
-END(__memcpy)
+END(__memcpy_a53)
diff --git a/libc/include/android/legacy_get_device_api_level_inlines.h b/libc/arch-arm/cortex-a53/bionic/memmove.S
similarity index 86%
copy from libc/include/android/legacy_get_device_api_level_inlines.h
copy to libc/arch-arm/cortex-a53/bionic/memmove.S
index b60123c..741acb3 100644
--- a/libc/include/android/legacy_get_device_api_level_inlines.h
+++ b/libc/arch-arm/cortex-a53/bionic/memmove.S
@@ -26,13 +26,7 @@
* SUCH DAMAGE.
*/
-#pragma once
+#define MEMMOVE memmove_a53
+#define MEMCPY __memcpy_a53
-#include <sys/cdefs.h>
-
-#if __ANDROID_API__ < __ANDROID_API_Q__
-
-#define __BIONIC_GET_DEVICE_API_LEVEL_INLINE static __inline
-#include <bits/get_device_api_level_inlines.h>
-
-#endif
+#include <arch-arm/denver/bionic/memmove.S>
diff --git a/libc/arch-arm/cortex-a7/bionic/memcpy.S b/libc/arch-arm/cortex-a7/bionic/memcpy.S
index 0bab6ee..2f32d2e 100644
--- a/libc/arch-arm/cortex-a7/bionic/memcpy.S
+++ b/libc/arch-arm/cortex-a7/bionic/memcpy.S
@@ -64,7 +64,7 @@
.arch armv7-a
// Prototype: void *memcpy (void *dst, const void *src, size_t count).
-ENTRY(__memcpy)
+ENTRY(__memcpy_a7)
pld [r1, #64]
push {r0, lr}
.cfi_def_cfa_offset 8
@@ -72,4 +72,4 @@
.cfi_rel_offset lr, 4
#include "memcpy_base.S"
-END(__memcpy)
+END(__memcpy_a7)
diff --git a/libc/include/android/legacy_get_device_api_level_inlines.h b/libc/arch-arm/cortex-a7/bionic/memmove.S
similarity index 86%
copy from libc/include/android/legacy_get_device_api_level_inlines.h
copy to libc/arch-arm/cortex-a7/bionic/memmove.S
index b60123c..17ead5a 100644
--- a/libc/include/android/legacy_get_device_api_level_inlines.h
+++ b/libc/arch-arm/cortex-a7/bionic/memmove.S
@@ -26,13 +26,7 @@
* SUCH DAMAGE.
*/
-#pragma once
+#define MEMMOVE memmove_a7
+#define MEMCPY __memcpy_a7
-#include <sys/cdefs.h>
-
-#if __ANDROID_API__ < __ANDROID_API_Q__
-
-#define __BIONIC_GET_DEVICE_API_LEVEL_INLINE static __inline
-#include <bits/get_device_api_level_inlines.h>
-
-#endif
+#include <arch-arm/denver/bionic/memmove.S>
diff --git a/libc/arch-arm/cortex-a7/bionic/memset.S b/libc/arch-arm/cortex-a7/bionic/memset.S
index 72ee613..d7d3b34 100644
--- a/libc/arch-arm/cortex-a7/bionic/memset.S
+++ b/libc/arch-arm/cortex-a7/bionic/memset.S
@@ -41,7 +41,7 @@
// arch. The code generated is exactly the same.
.arch armv7-a
-ENTRY(__memset_chk)
+ENTRY(__memset_chk_a7)
cmp r2, r3
bls memset
@@ -51,9 +51,9 @@
.cfi_rel_offset lr, 0
bl __memset_chk_fail
-END(__memset_chk)
+END(__memset_chk_a7)
-ENTRY(memset)
+ENTRY(memset_a7)
mov r3, r0
// At this point only d0, d1 are going to be used below.
vdup.8 q0, r1
@@ -160,4 +160,4 @@
strbcs r1, [r3], #1
strbcs r1, [r3], #1
bx lr
-END(memset)
+END(memset_a7)
diff --git a/libc/arch-arm/cortex-a9/bionic/memcpy.S b/libc/arch-arm/cortex-a9/bionic/memcpy.S
index a71c9d2..e78a7da 100644
--- a/libc/arch-arm/cortex-a9/bionic/memcpy.S
+++ b/libc/arch-arm/cortex-a9/bionic/memcpy.S
@@ -39,15 +39,15 @@
.thumb
.thumb_func
-ENTRY(__memcpy)
+ENTRY(__memcpy_a9)
pld [r1, #0]
stmfd sp!, {r0, lr}
.cfi_def_cfa_offset 8
.cfi_rel_offset r0, 0
.cfi_rel_offset lr, 4
pld [r1, #64]
-END(__memcpy)
+END(__memcpy_a9)
-#define MEMCPY_BASE __memcpy_base
-#define MEMCPY_BASE_ALIGNED __memcpy_base_aligned
+#define MEMCPY_BASE __memcpy_base_a9
+#define MEMCPY_BASE_ALIGNED __memcpy_base_aligned_a9
#include "memcpy_base.S"
diff --git a/libc/arch-arm/cortex-a9/bionic/memcpy_base.S b/libc/arch-arm/cortex-a9/bionic/memcpy_base.S
index 966b9b3..39da7ff 100644
--- a/libc/arch-arm/cortex-a9/bionic/memcpy_base.S
+++ b/libc/arch-arm/cortex-a9/bionic/memcpy_base.S
@@ -32,6 +32,12 @@
* cache line.
*/
+ .syntax unified
+
+ // To avoid warning about deprecated instructions, add an explicit
+ // arch. The code generated is exactly the same.
+ .arch armv7-a
+
ENTRY_PRIVATE(MEMCPY_BASE)
.cfi_def_cfa_offset 8
.cfi_rel_offset r0, 0
diff --git a/libc/include/android/legacy_get_device_api_level_inlines.h b/libc/arch-arm/cortex-a9/bionic/memmove.S
similarity index 86%
rename from libc/include/android/legacy_get_device_api_level_inlines.h
rename to libc/arch-arm/cortex-a9/bionic/memmove.S
index b60123c..a457633 100644
--- a/libc/include/android/legacy_get_device_api_level_inlines.h
+++ b/libc/arch-arm/cortex-a9/bionic/memmove.S
@@ -26,13 +26,7 @@
* SUCH DAMAGE.
*/
-#pragma once
+#define MEMMOVE memmove_a9
+#define MEMCPY __memcpy_a9
-#include <sys/cdefs.h>
-
-#if __ANDROID_API__ < __ANDROID_API_Q__
-
-#define __BIONIC_GET_DEVICE_API_LEVEL_INLINE static __inline
-#include <bits/get_device_api_level_inlines.h>
-
-#endif
+#include <arch-arm/denver/bionic/memmove.S>
diff --git a/libc/arch-arm/cortex-a9/bionic/memset.S b/libc/arch-arm/cortex-a9/bionic/memset.S
index d00231b..cf66e86 100644
--- a/libc/arch-arm/cortex-a9/bionic/memset.S
+++ b/libc/arch-arm/cortex-a9/bionic/memset.S
@@ -36,7 +36,7 @@
.fpu neon
.syntax unified
-ENTRY(__memset_chk)
+ENTRY(__memset_chk_a9)
cmp r2, r3
bls memset
@@ -46,10 +46,10 @@
.cfi_rel_offset lr, 0
bl __memset_chk_fail
-END(__memset_chk)
+END(__memset_chk_a9)
/* memset() returns its first argument. */
-ENTRY(memset)
+ENTRY(memset_a9)
// The neon memset only wins for less than 132.
cmp r2, #132
bhi .L_memset_large_copy
@@ -158,4 +158,4 @@
movs r2, r2, lsl #2
strbcs r1, [r0]
ldmfd sp!, {r0, r4-r7, pc}
-END(memset)
+END(memset_a9)
diff --git a/libc/arch-arm/cortex-a9/bionic/strcat.S b/libc/arch-arm/cortex-a9/bionic/strcat.S
index 9077a74..430748f 100644
--- a/libc/arch-arm/cortex-a9/bionic/strcat.S
+++ b/libc/arch-arm/cortex-a9/bionic/strcat.S
@@ -57,6 +57,10 @@
.syntax unified
+ // To avoid warning about deprecated instructions, add an explicit
+ // arch. The code generated is exactly the same.
+ .arch armv7-a
+
.thumb
.thumb_func
@@ -80,7 +84,7 @@
\cmd \reg, \label
.endm // m_copy_byte
-ENTRY(strcat)
+ENTRY(strcat_a9)
// Quick check to see if src is empty.
ldrb r2, [r1]
pld [r1, #0]
@@ -552,4 +556,4 @@
.Lstrcat_r0_update:
sub r0, r0, #1
b .Lstrcat_r0_scan_done
-END(strcat)
+END(strcat_a9)
diff --git a/libc/arch-arm/cortex-a9/bionic/strcmp.S b/libc/arch-arm/cortex-a9/bionic/strcmp.S
index ba191d6..ba7ea13 100644
--- a/libc/arch-arm/cortex-a9/bionic/strcmp.S
+++ b/libc/arch-arm/cortex-a9/bionic/strcmp.S
@@ -52,12 +52,16 @@
.syntax unified
+// To avoid warning about deprecated instructions, add an explicit
+// arch. The code generated is exactly the same.
+.arch armv7-a
+
#if defined (__thumb__)
.thumb
.thumb_func
#endif
-ENTRY(strcmp)
+ENTRY(strcmp_a9)
/* Use LDRD whenever possible. */
/* The main thing to look out for when comparing large blocks is that
@@ -544,4 +548,4 @@
adds sp, sp, #16
bx lr
-END(strcmp)
+END(strcmp_a9)
diff --git a/libc/arch-arm/cortex-a9/bionic/string_copy.S b/libc/arch-arm/cortex-a9/bionic/string_copy.S
index 642db0f..3605b7a 100644
--- a/libc/arch-arm/cortex-a9/bionic/string_copy.S
+++ b/libc/arch-arm/cortex-a9/bionic/string_copy.S
@@ -64,6 +64,10 @@
.thumb
.thumb_func
+ // To avoid warning about deprecated instructions, add an explicit
+ // arch. The code generated is exactly the same.
+ .arch armv7-a
+
#if defined(STPCPY)
.macro m_push
push {r4, r5, lr}
@@ -100,9 +104,9 @@
.endm // m_copy_byte
#if defined(STPCPY)
-ENTRY(stpcpy)
+ENTRY(stpcpy_a9)
#else
-ENTRY(strcpy)
+ENTRY(strcpy_a9)
#endif
// Unroll the first 8 bytes that will be copied.
m_push
@@ -536,7 +540,7 @@
#endif
m_ret inst=pop
#if defined(STPCPY)
-END(stpcpy)
+END(stpcpy_a9)
#else
-END(strcpy)
+END(strcpy_a9)
#endif
diff --git a/libc/arch-arm/cortex-a9/bionic/strlen.S b/libc/arch-arm/cortex-a9/bionic/strlen.S
index b92b043..ffebc9d 100644
--- a/libc/arch-arm/cortex-a9/bionic/strlen.S
+++ b/libc/arch-arm/cortex-a9/bionic/strlen.S
@@ -57,10 +57,14 @@
.syntax unified
+ // To avoid warning about deprecated instructions, add an explicit
+ // arch. The code generated is exactly the same.
+ .arch armv7-a
+
.thumb
.thumb_func
-ENTRY(strlen)
+ENTRY(strlen_a9)
pld [r0, #0]
mov r1, r0
@@ -164,4 +168,4 @@
sub r0, r1, r0
sub r0, r0, #1
bx lr
-END(strlen)
+END(strlen_a9)
diff --git a/libc/arch-arm/denver/bionic/memcpy.S b/libc/arch-arm/denver/bionic/memcpy.S
index f082542..5edee1e 100644
--- a/libc/arch-arm/denver/bionic/memcpy.S
+++ b/libc/arch-arm/denver/bionic/memcpy.S
@@ -65,14 +65,14 @@
// arch. The code generated is exactly the same.
.arch armv7-a
-ENTRY(__memcpy)
+ENTRY(__memcpy_denver)
pld [r1, #64]
push {r0, lr}
.cfi_def_cfa_offset 8
.cfi_rel_offset r0, 0
.cfi_rel_offset lr, 4
-END(__memcpy)
+END(__memcpy_denver)
-#define MEMCPY_BASE __memcpy_base
-#define MEMCPY_BASE_ALIGNED __memcpy_base_aligned
+#define MEMCPY_BASE __memcpy_base_denver
+#define MEMCPY_BASE_ALIGNED __memcpy_base_aligned_denver
#include "memcpy_base.S"
diff --git a/libc/arch-arm/denver/bionic/memmove.S b/libc/arch-arm/denver/bionic/memmove.S
index 74d2b31..13c90ef 100644
--- a/libc/arch-arm/denver/bionic/memmove.S
+++ b/libc/arch-arm/denver/bionic/memmove.S
@@ -29,6 +29,14 @@
#include <private/bionic_asm.h>
+#ifndef MEMMOVE
+# define MEMMOVE memmove_denver
+#endif
+
+#ifndef MEMCPY
+# define MEMCPY __memcpy_denver
+#endif
+
.text
.syntax unified
.fpu neon
@@ -40,7 +48,7 @@
#define PREFETCH_DISTANCE_MID (CACHE_LINE_SIZE*4)
#define PREFETCH_DISTANCE_FAR (CACHE_LINE_SIZE*16)
-ENTRY(memmove)
+ENTRY(MEMMOVE)
cmp r2, #0
cmpne r0, r1
bxeq lr
@@ -50,7 +58,7 @@
bhi .L_reversed_memcpy
.L_jump_to_memcpy:
- b __memcpy
+ b MEMCPY
.L_reversed_memcpy:
push {r0, lr}
@@ -277,6 +285,4 @@
pop {r0, pc}
-END(memmove)
-
-ALIAS_SYMBOL(memcpy, memmove)
+END(MEMMOVE)
diff --git a/libc/arch-arm/denver/bionic/memset.S b/libc/arch-arm/denver/bionic/memset.S
index 88ffe5c..198ecf3 100644
--- a/libc/arch-arm/denver/bionic/memset.S
+++ b/libc/arch-arm/denver/bionic/memset.S
@@ -39,7 +39,7 @@
.fpu neon
.syntax unified
-ENTRY(__memset_chk)
+ENTRY(__memset_chk_denver)
cmp r2, r3
bls memset
@@ -49,9 +49,9 @@
.cfi_rel_offset lr, 0
bl __memset_chk_fail
-END(__memset_chk)
+END(__memset_chk_denver)
-ENTRY(memset)
+ENTRY(memset_denver)
pldw [r0]
mov r3, r0
@@ -183,4 +183,4 @@
strbcs r1, [r3]
2:
bx lr
-END(memset)
+END(memset_denver)
diff --git a/libc/arch-arm/dynamic_function_dispatch.cpp b/libc/arch-arm/dynamic_function_dispatch.cpp
new file mode 100644
index 0000000..17f0087
--- /dev/null
+++ b/libc/arch-arm/dynamic_function_dispatch.cpp
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#include <fcntl.h>
+#include <sys/syscall.h>
+
+extern "C" {
+
+enum CpuVariant {
+ kUnknown = 0,
+ kGeneric,
+ kCortexA7,
+ kCortexA9,
+ kCortexA53,
+ kCortexA55,
+ kDenver,
+ kKrait,
+ kKryo,
+};
+
+static constexpr int MAX_CPU_NAME_LEN = 12;
+struct CpuVariantNames {
+ char name[MAX_CPU_NAME_LEN];
+ CpuVariant variant;
+};
+
+static constexpr CpuVariantNames cpu_variant_names[] = {
+ {"cortex-a76", kCortexA55},
+ {"cortex-a75", kCortexA55},
+ {"kryo", kKryo},
+ {"cortex-a73", kCortexA55},
+ {"cortex-a55", kCortexA55},
+ {"cortex-a53", kCortexA53},
+ {"krait", kKrait},
+ {"cortex-a9", kCortexA9},
+ {"cortex-a7", kCortexA7},
+ {"denver", kDenver},
+ // kUnknown indicates the end of this array.
+ {"", kUnknown},
+};
+
+static long ifunc_open(const char* pathname) {
+ register long r0 __asm__("r0") = AT_FDCWD;
+ register long r1 __asm__("r1") = reinterpret_cast<long>(pathname);
+ register long r2 __asm__("r2") = O_RDONLY;
+ register long r3 __asm__("r3") = 0;
+ register long r7 __asm__("r7") = __NR_openat;
+ __asm__ volatile("swi #0" : "=r"(r0) : "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r7));
+ return r0;
+}
+
+static ssize_t ifunc_read(int fd, void* buf, size_t count) {
+ register long r0 __asm__("r0") = fd;
+ register long r1 __asm__("r1") = reinterpret_cast<long>(buf);
+ register long r2 __asm__("r2") = count;
+ register long r7 __asm__("r7") = __NR_read;
+ __asm__ volatile("swi #0" : "=r"(r0) : "r"(r0), "r"(r1), "r"(r2), "r"(r7) : "memory");
+ return r0;
+}
+
+static int ifunc_close(int fd) {
+ register long r0 __asm__("r0") = fd;
+ register long r7 __asm__("r7") = __NR_close;
+ __asm__ volatile("swi #0" : "=r"(r0) : "r"(r0), "r"(r7));
+ return r0;
+}
+
+#define DEFINE_IFUNC(name) \
+ name##_func name __attribute__((ifunc(#name "_resolver"))); \
+ __attribute__((visibility("hidden"))) \
+ name##_func* name##_resolver()
+
+#define DECLARE_FUNC(type, name) \
+ __attribute__((visibility("hidden"))) \
+ type name
+
+#define RETURN_FUNC(type, name) { \
+ DECLARE_FUNC(type, name); \
+ return name; \
+ }
+
+static CpuVariant init_cpu_variant() {
+ int fd = ifunc_open("/dev/cpu_variant:arm");
+ if (fd < 0) return kGeneric;
+
+ char name[MAX_CPU_NAME_LEN];
+
+ int bytes_read, total_read = 0;
+ while (total_read < MAX_CPU_NAME_LEN - 1 &&
+ (bytes_read = ifunc_read(fd, name + total_read,
+ MAX_CPU_NAME_LEN - 1 - total_read)) > 0) {
+ total_read += bytes_read;
+ }
+ ifunc_close(fd);
+
+ if (bytes_read != 0) {
+ // The file is too big. We haven't reach the end. Or maybe there is an
+ // error when reading.
+ return kGeneric;
+ }
+ name[total_read] = 0;
+
+ typedef int strcmp_func(const char* __lhs, const char* __rhs);
+ DECLARE_FUNC(strcmp_func, strcmp_a15);
+
+ const CpuVariantNames* cpu_variant = cpu_variant_names;
+ while (cpu_variant->variant != kUnknown) {
+ if (strcmp_a15(cpu_variant->name, name) == 0) {
+ return cpu_variant->variant;
+ }
+ cpu_variant++;
+ }
+ return kGeneric;
+}
+
+static CpuVariant get_cpu_variant() {
+ static CpuVariant cpu_variant = kUnknown;
+ if (cpu_variant == kUnknown) {
+ cpu_variant = init_cpu_variant();
+ }
+ return cpu_variant;
+}
+
+typedef void* memmove_func(void* __dst, const void* __src, size_t __n);
+DEFINE_IFUNC(memmove) {
+ switch(get_cpu_variant()) {
+ case kCortexA7:
+ RETURN_FUNC(memmove_func, memmove_a7);
+ case kCortexA9:
+ RETURN_FUNC(memmove_func, memmove_a9);
+ case kKrait:
+ RETURN_FUNC(memmove_func, memmove_krait);
+ case kCortexA53:
+ RETURN_FUNC(memmove_func, memmove_a53);
+ case kCortexA55:
+ case kDenver:
+ RETURN_FUNC(memmove_func, memmove_denver);
+ case kKryo:
+ RETURN_FUNC(memmove_func, memmove_kryo);
+ default:
+ RETURN_FUNC(memmove_func, memmove_a15);
+ }
+}
+
+typedef void* memcpy_func(void*, const void*, size_t);
+DEFINE_IFUNC(memcpy) {
+ return memmove_resolver();
+}
+
+typedef void* __memset_chk_func(void* s, int c, size_t n, size_t n2);
+DEFINE_IFUNC(__memset_chk) {
+ switch(get_cpu_variant()) {
+ case kCortexA7:
+ case kCortexA53:
+ case kCortexA55:
+ case kKryo:
+ RETURN_FUNC(__memset_chk_func, __memset_chk_a7);
+ case kCortexA9:
+ RETURN_FUNC(__memset_chk_func, __memset_chk_a9);
+ case kKrait:
+ RETURN_FUNC(__memset_chk_func, __memset_chk_krait);
+ case kDenver:
+ RETURN_FUNC(__memset_chk_func, __memset_chk_denver);
+ default:
+ RETURN_FUNC(__memset_chk_func, __memset_chk_a15);
+ }
+}
+
+typedef void* memset_func(void* __dst, int __ch, size_t __n);
+DEFINE_IFUNC(memset) {
+ switch(get_cpu_variant()) {
+ case kCortexA7:
+ case kCortexA53:
+ case kCortexA55:
+ case kKryo:
+ RETURN_FUNC(memset_func, memset_a7);
+ case kCortexA9:
+ RETURN_FUNC(memset_func, memset_a9);
+ case kKrait:
+ RETURN_FUNC(memset_func, memset_krait);
+ case kDenver:
+ RETURN_FUNC(memset_func, memset_denver);
+ default:
+ RETURN_FUNC(memset_func, memset_a15);
+ }
+}
+
+typedef char* strcpy_func(char* __dst, const char* __src);
+DEFINE_IFUNC(strcpy) {
+ switch(get_cpu_variant()) {
+ case kCortexA9:
+ RETURN_FUNC(strcpy_func, strcpy_a9);
+ default:
+ RETURN_FUNC(strcpy_func, strcpy_a15);
+ }
+}
+
+typedef char* stpcpy_func(char* __dst, const char* __src);
+DEFINE_IFUNC(stpcpy) {
+ switch(get_cpu_variant()) {
+ case kCortexA9:
+ RETURN_FUNC(stpcpy_func, stpcpy_a9);
+ default:
+ RETURN_FUNC(stpcpy_func, stpcpy_a15);
+ }
+}
+
+typedef char* strcat_func(char* __dst, const char* __src);
+DEFINE_IFUNC(strcat) {
+ switch(get_cpu_variant()) {
+ case kCortexA9:
+ RETURN_FUNC(strcat_func, strcat_a9);
+ default:
+ RETURN_FUNC(strcat_func, strcat_a15);
+ }
+}
+
+typedef int strcmp_func(const char* __lhs, const char* __rhs);
+DEFINE_IFUNC(strcmp) {
+ switch(get_cpu_variant()) {
+ case kCortexA9:
+ RETURN_FUNC(strcmp_func, strcmp_a9);
+ case kCortexA55:
+ case kKrait:
+ case kKryo:
+ RETURN_FUNC(strcmp_func, strcmp_krait);
+ default:
+ RETURN_FUNC(strcmp_func, strcmp_a15);
+ }
+}
+
+typedef size_t strlen_func(const char* __s);
+DEFINE_IFUNC(strlen) {
+ switch(get_cpu_variant()) {
+ case kCortexA9:
+ RETURN_FUNC(strlen_func, strlen_a9);
+ default:
+ RETURN_FUNC(strlen_func, strlen_a15);
+ }
+}
+
+} // extern "C"
diff --git a/libc/arch-arm/generic/bionic/memmove.S b/libc/arch-arm/generic/bionic/memmove.S
index c52e17e..0cf82d1 100644
--- a/libc/arch-arm/generic/bionic/memmove.S
+++ b/libc/arch-arm/generic/bionic/memmove.S
@@ -464,10 +464,8 @@
b .Lmemcpy_bl4
END(bsd_safe_memcpy)
-ENTRY(memmove)
+ENTRY(memmove_generic)
stmfd sp!, {r0, lr}
bl bsd_safe_memcpy
ldmfd sp!, {r0, pc}
-END(memmove)
-
-ALIAS_SYMBOL(memcpy, memmove)
+END(memmove_generic)
diff --git a/libc/arch-arm/generic/bionic/memset.S b/libc/arch-arm/generic/bionic/memset.S
index 1fd0de1..e70002f 100644
--- a/libc/arch-arm/generic/bionic/memset.S
+++ b/libc/arch-arm/generic/bionic/memset.S
@@ -36,14 +36,14 @@
.syntax unified
-ENTRY(__memset_chk)
+ENTRY(__memset_chk_generic)
cmp r2, r3
bls memset
bl __memset_chk_fail
-END(__memset_chk)
+END(__memset_chk_generic)
-ENTRY(memset)
+ENTRY(memset_generic)
/* compute the offset to align the destination
* offset = (4-(src&3))&3 = -src & 3
*/
@@ -108,4 +108,4 @@
movs r2, r2, lsl #2
strbcs r1, [r0]
ldmfd sp!, {r0, r4-r7, pc}
-END(memset)
+END(memset_generic)
diff --git a/libc/include/android/legacy_get_device_api_level_inlines.h b/libc/arch-arm/generic/bionic/stpcpy.c
similarity index 86%
copy from libc/include/android/legacy_get_device_api_level_inlines.h
copy to libc/arch-arm/generic/bionic/stpcpy.c
index b60123c..0aabaa5 100644
--- a/libc/include/android/legacy_get_device_api_level_inlines.h
+++ b/libc/arch-arm/generic/bionic/stpcpy.c
@@ -26,13 +26,5 @@
* SUCH DAMAGE.
*/
-#pragma once
-
-#include <sys/cdefs.h>
-
-#if __ANDROID_API__ < __ANDROID_API_Q__
-
-#define __BIONIC_GET_DEVICE_API_LEVEL_INLINE static __inline
-#include <bits/get_device_api_level_inlines.h>
-
-#endif
+#define stpcpy stpcpy_generic
+#include <upstream-openbsd/lib/libc/string/stpcpy.c>
diff --git a/libc/include/android/legacy_get_device_api_level_inlines.h b/libc/arch-arm/generic/bionic/strcat.c
similarity index 86%
copy from libc/include/android/legacy_get_device_api_level_inlines.h
copy to libc/arch-arm/generic/bionic/strcat.c
index b60123c..8e70531 100644
--- a/libc/include/android/legacy_get_device_api_level_inlines.h
+++ b/libc/arch-arm/generic/bionic/strcat.c
@@ -26,13 +26,5 @@
* SUCH DAMAGE.
*/
-#pragma once
-
-#include <sys/cdefs.h>
-
-#if __ANDROID_API__ < __ANDROID_API_Q__
-
-#define __BIONIC_GET_DEVICE_API_LEVEL_INLINE static __inline
-#include <bits/get_device_api_level_inlines.h>
-
-#endif
+#define strcat strcat_generic
+#include <upstream-openbsd/lib/libc/string/strcat.c>
diff --git a/libc/arch-arm/generic/bionic/strcmp.S b/libc/arch-arm/generic/bionic/strcmp.S
index 10b6704..03225a0 100644
--- a/libc/arch-arm/generic/bionic/strcmp.S
+++ b/libc/arch-arm/generic/bionic/strcmp.S
@@ -31,6 +31,10 @@
.text
+ // To avoid warning about deprecated instructions, add an explicit
+ // arch. The code generated is exactly the same.
+ .arch armv7-a
+
#ifdef __ARMEB__
#define SHFT2LSB lsl
#define SHFT2LSBEQ lsleq
@@ -50,7 +54,7 @@
#define magic1(REG) REG
#define magic2(REG) REG, lsl #7
-ENTRY(strcmp)
+ENTRY(strcmp_generic)
pld [r0, #0]
pld [r1, #0]
eor r2, r0, r1
@@ -313,4 +317,4 @@
ldr r4, [sp], #4
ldr r5, [sp], #4
bx lr
-END(strcmp)
+END(strcmp_generic)
diff --git a/libc/arch-arm/generic/bionic/strcpy.S b/libc/arch-arm/generic/bionic/strcpy.S
index c0ab9e5..89bd699 100644
--- a/libc/arch-arm/generic/bionic/strcpy.S
+++ b/libc/arch-arm/generic/bionic/strcpy.S
@@ -33,7 +33,11 @@
.syntax unified
-ENTRY(strcpy)
+// To avoid warning about deprecated instructions, add an explicit
+// arch. The code generated is exactly the same.
+.arch armv7-a
+
+ENTRY(strcpy_generic)
pld [r1, #0]
eor r2, r0, r1
mov ip, r0
@@ -131,4 +135,4 @@
cmp r2, #0
bne 4b
bx lr
-END(strcpy)
+END(strcpy_generic)
diff --git a/libc/arch-arm/generic/bionic/strlen.c b/libc/arch-arm/generic/bionic/strlen.c
index 44bd72f..43d9e51 100644
--- a/libc/arch-arm/generic/bionic/strlen.c
+++ b/libc/arch-arm/generic/bionic/strlen.c
@@ -29,7 +29,7 @@
#include <string.h>
#include <stdint.h>
-size_t strlen(const char *s)
+size_t strlen_generic(const char *s)
{
__builtin_prefetch(s);
__builtin_prefetch(s+32);
diff --git a/libc/arch-arm/krait/bionic/memcpy.S b/libc/arch-arm/krait/bionic/memcpy.S
index 49fd040..6618b3a 100644
--- a/libc/arch-arm/krait/bionic/memcpy.S
+++ b/libc/arch-arm/krait/bionic/memcpy.S
@@ -42,7 +42,7 @@
.thumb
.thumb_func
-ENTRY(__memcpy)
+ENTRY(__memcpy_krait)
pld [r1, #64]
stmfd sp!, {r0, lr}
.cfi_adjust_cfa_offset 8
@@ -50,4 +50,4 @@
.cfi_rel_offset lr, 4
#include "memcpy_base.S"
-END(__memcpy)
+END(__memcpy_krait)
diff --git a/libc/arch-arm/krait/bionic/memcpy_base.S b/libc/arch-arm/krait/bionic/memcpy_base.S
index dc8ad2c..5b4b70d 100644
--- a/libc/arch-arm/krait/bionic/memcpy_base.S
+++ b/libc/arch-arm/krait/bionic/memcpy_base.S
@@ -41,8 +41,13 @@
#endif
.text
+ .syntax unified
.fpu neon
+ // To avoid warning about deprecated instructions, add an explicit
+ // arch. The code generated is exactly the same.
+ .arch armv7-a
+
.L_memcpy_base:
cmp r2, #4
blt .L_neon_lt4
diff --git a/libc/include/android/legacy_get_device_api_level_inlines.h b/libc/arch-arm/krait/bionic/memmove.S
similarity index 86%
copy from libc/include/android/legacy_get_device_api_level_inlines.h
copy to libc/arch-arm/krait/bionic/memmove.S
index b60123c..af85ea6 100644
--- a/libc/include/android/legacy_get_device_api_level_inlines.h
+++ b/libc/arch-arm/krait/bionic/memmove.S
@@ -26,13 +26,7 @@
* SUCH DAMAGE.
*/
-#pragma once
+#define MEMMOVE memmove_krait
+#define MEMCPY __memcpy_krait
-#include <sys/cdefs.h>
-
-#if __ANDROID_API__ < __ANDROID_API_Q__
-
-#define __BIONIC_GET_DEVICE_API_LEVEL_INLINE static __inline
-#include <bits/get_device_api_level_inlines.h>
-
-#endif
+#include <arch-arm/denver/bionic/memmove.S>
diff --git a/libc/arch-arm/krait/bionic/memset.S b/libc/arch-arm/krait/bionic/memset.S
index 228942c..675ab53 100644
--- a/libc/arch-arm/krait/bionic/memset.S
+++ b/libc/arch-arm/krait/bionic/memset.S
@@ -37,7 +37,7 @@
.fpu neon
.syntax unified
-ENTRY(__memset_chk)
+ENTRY(__memset_chk_krait)
cmp r2, r3
bls memset
@@ -47,10 +47,10 @@
.cfi_rel_offset lr, 0
bl __memset_chk_fail
-END(__memset_chk)
+END(__memset_chk_krait)
/* memset() returns its first argument. */
-ENTRY(memset)
+ENTRY(memset_krait)
mov r3, r0
vdup.8 q0, r1
@@ -82,4 +82,4 @@
strbcs r1, [r3], #1
strbcs r1, [r3], #1
bx lr
-END(memset)
+END(memset_krait)
diff --git a/libc/arch-arm/krait/bionic/strcmp.S b/libc/arch-arm/krait/bionic/strcmp.S
index b871c76..ec692e5 100644
--- a/libc/arch-arm/krait/bionic/strcmp.S
+++ b/libc/arch-arm/krait/bionic/strcmp.S
@@ -52,12 +52,16 @@
.syntax unified
+// To avoid warning about deprecated instructions, add an explicit
+// arch. The code generated is exactly the same.
+.arch armv7-a
+
#if defined (__thumb__)
.thumb
.thumb_func
#endif
-ENTRY(strcmp)
+ENTRY(strcmp_krait)
/* Use LDRD whenever possible. */
/* The main thing to look out for when comparing large blocks is that
@@ -482,4 +486,4 @@
.cfi_restore r7
bx lr
-END(strcmp)
+END(strcmp_krait)
diff --git a/libc/arch-arm/kryo/bionic/memcpy.S b/libc/arch-arm/kryo/bionic/memcpy.S
index 74036ef..250f7bc 100644
--- a/libc/arch-arm/kryo/bionic/memcpy.S
+++ b/libc/arch-arm/kryo/bionic/memcpy.S
@@ -33,8 +33,14 @@
#define PLDOFFS (16)
#define PLDSIZE (128) /* L2 cache line size */
+ .syntax unified
+
+ // To avoid warning about deprecated instructions, add an explicit
+ // arch. The code generated is exactly the same.
+ .arch armv7-a
+
.code 32
-ENTRY(__memcpy)
+ENTRY(__memcpy_kryo)
push {r0}
.cfi_def_cfa_offset 4
.cfi_rel_offset r0, 0
@@ -123,4 +129,4 @@
pop {r0}
bx lr
-END(__memcpy)
+END(__memcpy_kryo)
diff --git a/libc/include/android/legacy_get_device_api_level_inlines.h b/libc/arch-arm/kryo/bionic/memmove.S
similarity index 86%
copy from libc/include/android/legacy_get_device_api_level_inlines.h
copy to libc/arch-arm/kryo/bionic/memmove.S
index b60123c..d0fdd8f 100644
--- a/libc/include/android/legacy_get_device_api_level_inlines.h
+++ b/libc/arch-arm/kryo/bionic/memmove.S
@@ -26,13 +26,7 @@
* SUCH DAMAGE.
*/
-#pragma once
+#define MEMMOVE memmove_kryo
+#define MEMCPY __memcpy_kryo
-#include <sys/cdefs.h>
-
-#if __ANDROID_API__ < __ANDROID_API_Q__
-
-#define __BIONIC_GET_DEVICE_API_LEVEL_INLINE static __inline
-#include <bits/get_device_api_level_inlines.h>
-
-#endif
+#include <arch-arm/denver/bionic/memmove.S>
diff --git a/libc/include/android/legacy_get_device_api_level_inlines.h b/libc/arch-arm/static_function_dispatch.S
similarity index 72%
copy from libc/include/android/legacy_get_device_api_level_inlines.h
copy to libc/arch-arm/static_function_dispatch.S
index b60123c..f3dd741 100644
--- a/libc/include/android/legacy_get_device_api_level_inlines.h
+++ b/libc/arch-arm/static_function_dispatch.S
@@ -26,13 +26,19 @@
* SUCH DAMAGE.
*/
-#pragma once
+#include <private/bionic_asm.h>
-#include <sys/cdefs.h>
+#define FUNCTION_DELEGATE(name, impl) \
+ENTRY(name); \
+ b impl; \
+END(name)
-#if __ANDROID_API__ < __ANDROID_API_Q__
-
-#define __BIONIC_GET_DEVICE_API_LEVEL_INLINE static __inline
-#include <bits/get_device_api_level_inlines.h>
-
-#endif
+FUNCTION_DELEGATE(memmove, memmove_generic)
+FUNCTION_DELEGATE(memcpy, memmove_generic)
+FUNCTION_DELEGATE(memset, memset_generic)
+FUNCTION_DELEGATE(__memset_chk, __memset_chk_generic)
+FUNCTION_DELEGATE(strcpy, strcpy_generic)
+FUNCTION_DELEGATE(stpcpy, stpcpy_generic)
+FUNCTION_DELEGATE(strcat, strcat_generic)
+FUNCTION_DELEGATE(strcmp, strcmp_generic)
+FUNCTION_DELEGATE(strlen, strlen_generic)
diff --git a/libc/arch-arm64/bionic/setjmp.S b/libc/arch-arm64/bionic/setjmp.S
index 5e62c28..a2b2370 100644
--- a/libc/arch-arm64/bionic/setjmp.S
+++ b/libc/arch-arm64/bionic/setjmp.S
@@ -27,6 +27,7 @@
*/
#include <private/bionic_asm.h>
+#include <private/bionic_constants.h>
// According to AARCH64 PCS document we need to save the following
// registers:
@@ -44,10 +45,12 @@
// word name description
// 0 sigflag/cookie setjmp cookie in top 31 bits, signal mask flag in low bit
// 1 sigmask signal mask (not used with _setjmp / _longjmp)
-// 2 core_base base of core registers (x19-x30, sp)
-// 15 float_base base of float registers (d8-d15)
-// 23 checksum checksum of core registers
-// 24 reserved reserved entries (room to grow)
+// 2 core_base base of core registers (x18-x30, sp)
+// (We only store the low bits of x18 to avoid leaking the
+// shadow call stack address into memory.)
+// 16 float_base base of float registers (d8-d15)
+// 24 checksum checksum of core registers
+// 25 reserved reserved entries (room to grow)
// 32
#define _JB_SIGFLAG 0
@@ -58,18 +61,20 @@
#define _JB_X24_X25 (_JB_X26_X27 + 2)
#define _JB_X22_X23 (_JB_X24_X25 + 2)
#define _JB_X20_X21 (_JB_X22_X23 + 2)
-#define _JB_X19 (_JB_X20_X21 + 2)
-#define _JB_D14_D15 (_JB_X19 + 1)
+#define _JB_SCS_X19 (_JB_X20_X21 + 2)
+#define _JB_D14_D15 (_JB_SCS_X19 + 2)
#define _JB_D12_D13 (_JB_D14_D15 + 2)
#define _JB_D10_D11 (_JB_D12_D13 + 2)
#define _JB_D8_D9 (_JB_D10_D11 + 2)
#define _JB_CHECKSUM (_JB_D8_D9 + 2)
+#define SCS_MASK (SCS_SIZE - 1)
#define MANGLE_REGISTERS 1
#define USE_CHECKSUM 1
.macro m_mangle_registers reg, sp_reg
#if MANGLE_REGISTERS
+ eor x3, x3, \reg
eor x19, x19, \reg
eor x20, x20, \reg
eor x21, x21, \reg
@@ -88,7 +93,7 @@
.macro m_calculate_checksum dst, src, scratch
mov \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
+ .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
ldr \scratch, [\src, #(\i * 8)]
eor \dst, \dst, \scratch
.endr
@@ -151,6 +156,9 @@
// Mask off the signal flag bit.
bic x1, x1, #1
+ // Mask off the high bits of the shadow call stack pointer.
+ and x3, x18, #SCS_MASK
+
// Save core registers.
mov x10, sp
m_mangle_registers x1, sp_reg=x10
@@ -160,7 +168,7 @@
stp x24, x25, [x0, #(_JB_X24_X25 * 8)]
stp x22, x23, [x0, #(_JB_X22_X23 * 8)]
stp x20, x21, [x0, #(_JB_X20_X21 * 8)]
- str x19, [x0, #(_JB_X19 * 8)]
+ stp x3, x19, [x0, #(_JB_SCS_X19 * 8)]
m_unmangle_registers x1, sp_reg=x10
// Save floating point registers.
@@ -248,10 +256,14 @@
ldp x24, x25, [x0, #(_JB_X24_X25 * 8)]
ldp x22, x23, [x0, #(_JB_X22_X23 * 8)]
ldp x20, x21, [x0, #(_JB_X20_X21 * 8)]
- ldr x19, [x0, #(_JB_X19 * 8)]
+ ldp x3, x19, [x0, #(_JB_SCS_X19 * 8)]
m_unmangle_registers x2, sp_reg=x10
mov sp, x10
+ // Restore the low bits of the shadow call stack pointer.
+ and x18, x18, #~SCS_MASK
+ orr x18, x3, x18
+
stp x0, x1, [sp, #-16]!
.cfi_adjust_cfa_offset 16
.cfi_rel_offset x0, 0
diff --git a/libc/bionic/libc_init_dynamic.cpp b/libc/bionic/libc_init_dynamic.cpp
index 6b2d86f..fc68b8a 100644
--- a/libc/bionic/libc_init_dynamic.cpp
+++ b/libc/bionic/libc_init_dynamic.cpp
@@ -137,9 +137,3 @@
args.argv + __libc_shared_globals->initial_linker_arg_count,
args.envp));
}
-
-extern "C" int android_get_application_target_sdk_version();
-
-int bionic_get_application_target_sdk_version() {
- return android_get_application_target_sdk_version();
-}
diff --git a/libc/bionic/libc_init_static.cpp b/libc/bionic/libc_init_static.cpp
index a54840b..ef1c393 100644
--- a/libc/bionic/libc_init_static.cpp
+++ b/libc/bionic/libc_init_static.cpp
@@ -152,10 +152,6 @@
return g_target_sdk_version;
}
-int bionic_get_application_target_sdk_version() {
- return android_get_application_target_sdk_version();
-}
-
extern "C" void android_set_application_target_sdk_version(int target) {
g_target_sdk_version = target;
}
diff --git a/libc/bionic/malloc_common.cpp b/libc/bionic/malloc_common.cpp
index 3a94084..8d8d420 100644
--- a/libc/bionic/malloc_common.cpp
+++ b/libc/bionic/malloc_common.cpp
@@ -271,6 +271,7 @@
static const char* HEAPPROFD_SHARED_LIB = "heapprofd_client.so";
static const char* HEAPPROFD_PREFIX = "heapprofd";
+static const char* HEAPPROFD_PROPERTY_ENABLE = "heapprofd.enable";
static const int HEAPPROFD_SIGNAL = __SIGRTMIN + 4;
enum FunctionEnum : uint8_t {
@@ -469,6 +470,39 @@
return true;
}
+static bool CheckLoadHeapprofd() {
+ // First check for heapprofd.enable. If it is set to "all", enable
+ // heapprofd for all processes. Otherwise, check heapprofd.enable.${prog},
+ // if it is set and not 0, enable heap profiling for this process.
+ char property_value[PROP_VALUE_MAX];
+ if (__system_property_get(HEAPPROFD_PROPERTY_ENABLE, property_value) == 0) {
+ return false;
+ }
+ if (strcmp(property_value, "all") == 0) {
+ return true;
+ }
+
+ char program_property[128];
+ int ret = snprintf(program_property, sizeof(program_property), "%s.%s",
+ HEAPPROFD_PROPERTY_ENABLE, getprogname());
+
+ if (ret < 0 || static_cast<size_t>(ret) >= sizeof(program_property)) {
+ if (ret < 0) {
+ error_log("Failed to concatenate heapprofd property %s.%s: %s",
+ HEAPPROFD_PROPERTY_ENABLE, getprogname(), strerror(errno));
+ } else {
+ error_log("Overflow in concatenating heapprofd property");
+ }
+ return false;
+ }
+
+ if (__system_property_get(program_property, property_value) == 0) {
+ return false;
+ }
+
+ return program_property[0] != '\0';
+}
+
static void ClearGlobalFunctions() {
for (size_t i = 0; i < FUNC_LAST; i++) {
g_functions[i] = nullptr;
@@ -572,6 +606,9 @@
} else if (CheckLoadMallocHooks(&options)) {
prefix = "hooks";
shared_lib = HOOKS_SHARED_LIB;
+ } else if (CheckLoadHeapprofd()) {
+ prefix = "heapprofd";
+ shared_lib = HEAPPROFD_SHARED_LIB;
} else {
return;
}
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index 720a3ae..6f632e8 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -39,6 +39,7 @@
#include <async_safe/log.h>
+#include "private/bionic_constants.h"
#include "private/bionic_defs.h"
#include "private/bionic_macros.h"
#include "private/bionic_ssp.h"
@@ -112,14 +113,19 @@
static void __init_shadow_call_stack(pthread_internal_t* thread __unused) {
#ifdef __aarch64__
- // Allocate the stack and store its address in register x18.
- // TODO(pcc): We ought to allocate a guard region here and then allocate the SCS at a random
- // location within it. This will provide greater security since it would mean that an attacker who
- // can read the pthread_internal_t won't be able to discover the address of the SCS. However,
- // doing so is blocked on a solution to b/118642754.
- char* scs = reinterpret_cast<char*>(
- mmap(nullptr, SCS_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0));
- thread->shadow_call_stack_guard_region = scs;
+ // Allocate the stack and store its address in register x18. The address is aligned to SCS_SIZE so
+ // that we only need to store the lower log2(SCS_SIZE) bits in jmp_buf.
+ // TODO(pcc): We ought to allocate a larger guard region here and then allocate the SCS at a
+ // random location within it. This will provide greater security since it would mean that an
+ // attacker who can read the pthread_internal_t won't be able to discover the address of the SCS.
+ // However, doing so is blocked on a solution to b/118642754.
+ char* scs_guard_region = reinterpret_cast<char*>(
+ mmap(nullptr, SCS_GUARD_REGION_SIZE, 0, MAP_PRIVATE | MAP_ANON, -1, 0));
+ thread->shadow_call_stack_guard_region = scs_guard_region;
+
+ char* scs =
+ reinterpret_cast<char*>(align_up(reinterpret_cast<uintptr_t>(scs_guard_region), SCS_SIZE));
+ mprotect(scs, SCS_SIZE, PROT_READ | PROT_WRITE);
__asm__ __volatile__("mov x18, %0" ::"r"(scs));
#endif
}
diff --git a/libc/bionic/pthread_exit.cpp b/libc/bionic/pthread_exit.cpp
index a884be5..2d4d6cf 100644
--- a/libc/bionic/pthread_exit.cpp
+++ b/libc/bionic/pthread_exit.cpp
@@ -33,6 +33,7 @@
#include <string.h>
#include <sys/mman.h>
+#include "private/bionic_constants.h"
#include "private/bionic_defs.h"
#include "private/ScopedSignalBlocker.h"
#include "pthread_internal.h"
@@ -105,7 +106,7 @@
#ifdef __aarch64__
// Free the shadow call stack and guard pages.
- munmap(thread->shadow_call_stack_guard_region, SCS_SIZE);
+ munmap(thread->shadow_call_stack_guard_region, SCS_GUARD_REGION_SIZE);
#endif
ThreadJoinState old_state = THREAD_NOT_JOINED;
diff --git a/libc/bionic/pthread_internal.cpp b/libc/bionic/pthread_internal.cpp
index 92786fe..2b7a99a 100644
--- a/libc/bionic/pthread_internal.cpp
+++ b/libc/bionic/pthread_internal.cpp
@@ -36,7 +36,6 @@
#include <async_safe/log.h>
#include "private/bionic_futex.h"
-#include "private/bionic_sdk_version.h"
#include "private/bionic_tls.h"
static pthread_internal_t* g_thread_list = nullptr;
@@ -114,7 +113,7 @@
}
// Historically we'd return null, but
- if (bionic_get_application_target_sdk_version() >= __ANDROID_API_O__) {
+ if (android_get_application_target_sdk_version() >= __ANDROID_API_O__) {
if (thread == nullptr) {
// This seems to be a common mistake, and it's relatively harmless because
// there will never be a valid thread at address 0, whereas other invalid
diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h
index 3d58121..81b885a 100644
--- a/libc/bionic/pthread_internal.h
+++ b/libc/bionic/pthread_internal.h
@@ -209,9 +209,6 @@
// Leave room for a guard page in the internally created signal stacks.
#define SIGNAL_STACK_SIZE (SIGNAL_STACK_SIZE_WITHOUT_GUARD + PTHREAD_GUARD_SIZE)
-// Size of the shadow call stack.
-#define SCS_SIZE (8 * 1024)
-
// Needed by fork.
__LIBC_HIDDEN__ extern void __bionic_atfork_run_prepare();
__LIBC_HIDDEN__ extern void __bionic_atfork_run_child();
diff --git a/libc/bionic/pthread_mutex.cpp b/libc/bionic/pthread_mutex.cpp
index fda0b93..d9ddf10 100644
--- a/libc/bionic/pthread_mutex.cpp
+++ b/libc/bionic/pthread_mutex.cpp
@@ -42,7 +42,6 @@
#include "private/bionic_constants.h"
#include "private/bionic_fortify.h"
#include "private/bionic_futex.h"
-#include "private/bionic_sdk_version.h"
#include "private/bionic_systrace.h"
#include "private/bionic_time_conversions.h"
#include "private/bionic_tls.h"
@@ -789,7 +788,7 @@
// ARM64. So make it noinline.
static int __attribute__((noinline)) HandleUsingDestroyedMutex(pthread_mutex_t* mutex,
const char* function_name) {
- if (bionic_get_application_target_sdk_version() >= __ANDROID_API_P__) {
+ if (android_get_application_target_sdk_version() >= __ANDROID_API_P__) {
__fortify_fatal("%s called on a destroyed mutex (%p)", function_name, mutex);
}
return EBUSY;
diff --git a/libc/bionic/semaphore.cpp b/libc/bionic/semaphore.cpp
index d401b66..e0486b4 100644
--- a/libc/bionic/semaphore.cpp
+++ b/libc/bionic/semaphore.cpp
@@ -41,7 +41,6 @@
#include "private/bionic_constants.h"
#include "private/bionic_futex.h"
-#include "private/bionic_sdk_version.h"
#include "private/bionic_time_conversions.h"
// In this implementation, a semaphore contains a
@@ -222,7 +221,7 @@
}
int result = __futex_wait_ex(sem_count_ptr, shared, shared | SEMCOUNT_MINUS_ONE, false, nullptr);
- if (bionic_get_application_target_sdk_version() >= __ANDROID_API_N__) {
+ if (android_get_application_target_sdk_version() >= __ANDROID_API_N__) {
if (result ==-EINTR) {
errno = EINTR;
return -1;
diff --git a/libc/include/android/api-level.h b/libc/include/android/api-level.h
index 3a8f926..a175857 100644
--- a/libc/include/android/api-level.h
+++ b/libc/include/android/api-level.h
@@ -35,6 +35,8 @@
#include <sys/cdefs.h>
+__BEGIN_DECLS
+
#ifndef __ANDROID_API_FUTURE__
/**
* Magic version number for an Android OS build which has
@@ -97,3 +99,39 @@
/** Names the "Q" API level (29), for comparisons against __ANDROID_API__. */
#define __ANDROID_API_Q__ 29
+
+/**
+ * Returns the `targetSdkVersion` of the caller, or `__ANDROID_API_FUTURE__`
+ * if there is no known target SDK version (for code not running in the
+ * context of an app).
+ *
+ * The returned values correspond to the named constants in `<android/api-level.h>`,
+ * and is equivalent to the AndroidManifest.xml `targetSdkVersion`.
+ *
+ * See also android_get_device_api_level().
+ *
+ * Available since API level 24.
+ */
+int android_get_application_target_sdk_version() __INTRODUCED_IN(24);
+
+#if __ANDROID_API__ < __ANDROID_API_Q__
+
+// android_get_device_api_level is a static inline before API level 29.
+#define __BIONIC_GET_DEVICE_API_LEVEL_INLINE static __inline
+#include <bits/get_device_api_level_inlines.h>
+#undef __BIONIC_GET_DEVICE_API_LEVEL_INLINE
+
+#else
+
+/**
+ * Returns the API level of the device we're actually running on, or -1 on failure.
+ * The returned values correspond to the named constants in `<android/api-level.h>`,
+ * and is equivalent to the Java `Build.VERSION.SDK_INT` API.
+ *
+ * See also android_get_application_target_sdk_version().
+ */
+int android_get_device_api_level() __INTRODUCED_IN(29);
+
+#endif
+
+__END_DECLS
diff --git a/libc/include/android/get_device_api_level.h b/libc/include/android/get_device_api_level.h
deleted file mode 100644
index 39609da..0000000
--- a/libc/include/android/get_device_api_level.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#pragma once
-
-/**
- * @file android/get_device_api_level.h
- * @brief Check the API level of the device we're actually running on.
- */
-
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-
-#if __ANDROID_API__ >= __ANDROID_API_Q__
-// This file is implemented as static inlines before API level 29.
-
-/**
- * Returns the API level of the device we're actually running on, or -1 on failure.
- * The returned values correspond to the named constants in <android/api-level.h>,
- * and is equivalent to the Java `Build.VERSION.SDK_INT` API.
- */
-int android_get_device_api_level() __INTRODUCED_IN(29);
-
-#endif
-
-__END_DECLS
-
-#include <android/legacy_get_device_api_level_inlines.h>
diff --git a/libc/include/android/versioning.h b/libc/include/android/versioning.h
index 6e4b8ab..01fa348 100644
--- a/libc/include/android/versioning.h
+++ b/libc/include/android/versioning.h
@@ -14,23 +14,16 @@
* limitations under the License.
*/
-#ifndef ANDROID_VERSIONING_H
-#define ANDROID_VERSIONING_H
+#pragma once
-#ifndef __STRING
-#define __STRING(x) #x
-#endif
-
-#define __INTRODUCED_IN(api_level) __attribute__((annotate("introduced_in=" __STRING(api_level))))
+#define __INTRODUCED_IN(api_level) __attribute__((annotate("introduced_in=" #api_level)))
#define __INTRODUCED_IN_FUTURE __attribute__((annotate("introduced_in_future")))
-#define __DEPRECATED_IN(api_level) __attribute__((annotate("deprecated_in=" __STRING(api_level))))
-#define __REMOVED_IN(api_level) __attribute__((annotate("obsoleted_in=" __STRING(api_level))))
-#define __INTRODUCED_IN_32(api_level) __attribute__((annotate("introduced_in_32=" __STRING(api_level))))
-#define __INTRODUCED_IN_64(api_level) __attribute__((annotate("introduced_in_64=" __STRING(api_level))))
-#define __INTRODUCED_IN_ARM(api_level) __attribute__((annotate("introduced_in_arm=" __STRING(api_level))))
-#define __INTRODUCED_IN_X86(api_level) __attribute__((annotate("introduced_in_x86=" __STRING(api_level))))
-#define __INTRODUCED_IN_MIPS(api_level) __attribute__((annotate("introduced_in_mips=" __STRING(api_level))))
+#define __DEPRECATED_IN(api_level) __attribute__((annotate("deprecated_in=" #api_level)))
+#define __REMOVED_IN(api_level) __attribute__((annotate("obsoleted_in=" #api_level)))
+#define __INTRODUCED_IN_32(api_level) __attribute__((annotate("introduced_in_32=" #api_level)))
+#define __INTRODUCED_IN_64(api_level) __attribute__((annotate("introduced_in_64=" #api_level)))
+#define __INTRODUCED_IN_ARM(api_level) __attribute__((annotate("introduced_in_arm=" #api_level)))
+#define __INTRODUCED_IN_X86(api_level) __attribute__((annotate("introduced_in_x86=" #api_level)))
+#define __INTRODUCED_IN_MIPS(api_level) __attribute__((annotate("introduced_in_mips=" #api_level)))
#define __VERSIONER_NO_GUARD __attribute__((annotate("versioner_no_guard")))
-
-#endif /* ANDROID_VERSIONING_H */
diff --git a/libc/include/bits/get_device_api_level_inlines.h b/libc/include/bits/get_device_api_level_inlines.h
index 8e17814..9c6e243 100644
--- a/libc/include/bits/get_device_api_level_inlines.h
+++ b/libc/include/bits/get_device_api_level_inlines.h
@@ -28,18 +28,20 @@
#pragma once
-#include <stdlib.h>
#include <sys/cdefs.h>
-#include <sys/system_properties.h>
#if !defined(__BIONIC_GET_DEVICE_API_LEVEL_INLINE)
-#define __BIONIC_GET_DEVICE_API_LEVEL_INLINE static __inline
+#define __BIONIC_GET_DEVICE_API_LEVEL_INLINE static inline /* for versioner */
#endif
__BEGIN_DECLS
+// Avoid circular dependencies since this is exposed from <sys/cdefs.h>.
+int __system_property_get(const char* __name, char* __value);
+int atoi(const char* __s) __attribute_pure__;
+
__BIONIC_GET_DEVICE_API_LEVEL_INLINE int android_get_device_api_level() {
- char value[PROP_VALUE_MAX] = { 0 };
+ char value[92] = { 0 };
if (__system_property_get("ro.build.version.sdk", value) < 1) return -1;
int api_level = atoi(value);
return (api_level > 0) ? api_level : -1;
diff --git a/libc/include/bits/ioctl.h b/libc/include/bits/ioctl.h
index 9ed1292..fd31a58 100644
--- a/libc/include/bits/ioctl.h
+++ b/libc/include/bits/ioctl.h
@@ -54,11 +54,8 @@
* type of the ioctl you prefer, ...), or
* - defining BIONIC_IOCTL_NO_SIGNEDNESS_OVERLOAD, which will make the
* overloading go away.
- *
- * FIXME: __has_extension is more or less a clang version check. Remove it when
- * we don't need to support old clang code.
*/
-#if __has_extension(overloadable_unmarked) && !defined(BIONIC_IOCTL_NO_SIGNEDNESS_OVERLOAD)
+#if !defined(BIONIC_IOCTL_NO_SIGNEDNESS_OVERLOAD)
/* enable_if(1) just exists to break overloading ties. */
int ioctl(int __fd, unsigned __request, ...) __overloadable __enable_if(1, "") __RENAME(ioctl);
#endif
diff --git a/libc/include/signal.h b/libc/include/signal.h
index 9d1030a..c788ca6 100644
--- a/libc/include/signal.h
+++ b/libc/include/signal.h
@@ -114,7 +114,7 @@
int pthread_kill(pthread_t __pthread, int __signal);
#if defined(__USE_GNU)
-int pthread_sigqueue(pthread_t __pthread, int __signal, const union sigval __value) __INTRODUCED_IN(__ANDROID_API_Q__);
+int pthread_sigqueue(pthread_t __pthread, int __signal, const union sigval __value) __INTRODUCED_IN(29);
#endif
int pthread_sigmask(int __how, const sigset_t* __new_set, sigset_t* __old_set);
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index 26a05c8..e9d0e4b 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -34,36 +34,10 @@
* @(#)cdefs.h 8.8 (Berkeley) 1/9/95
*/
-#ifndef _SYS_CDEFS_H_
-#define _SYS_CDEFS_H_
-
-#include <android/api-level.h>
+#pragma once
#define __BIONIC__ 1
-/*
- * Testing against Clang-specific extensions.
- */
-#ifndef __has_extension
-#define __has_extension __has_feature
-#endif
-#ifndef __has_feature
-#define __has_feature(x) 0
-#endif
-#ifndef __has_include
-#define __has_include(x) 0
-#endif
-#ifndef __has_builtin
-#define __has_builtin(x) 0
-#endif
-#ifndef __has_attribute
-#define __has_attribute(x) 0
-#endif
-
-#define __strong_alias(alias, sym) \
- __asm__(".global " #alias "\n" \
- #alias " = " #sym);
-
#if defined(__cplusplus)
#define __BEGIN_DECLS extern "C" {
#define __END_DECLS }
@@ -72,6 +46,10 @@
#define __END_DECLS
#endif
+#define __strong_alias(alias, sym) \
+ __asm__(".global " #alias "\n" \
+ #alias " = " #sym);
+
#if defined(__cplusplus)
#define __BIONIC_CAST(_k,_t,_v) (_k<_t>(_v))
#else
@@ -88,22 +66,19 @@
* strings produced by the __STRING macro, but this only works with ANSI C.
*/
-#define ___STRING(x) __STRING(x)
-#define ___CONCAT(x,y) __CONCAT(x,y)
-
#define __P(protos) protos /* full-blown ANSI C */
+
#define __CONCAT1(x,y) x ## y
#define __CONCAT(x,y) __CONCAT1(x,y)
+#define ___CONCAT(x,y) __CONCAT(x,y)
+
#define __STRING(x) #x
+#define ___STRING(x) __STRING(x)
#if defined(__cplusplus)
#define __inline inline /* convert to C++ keyword */
#endif /* !__cplusplus */
-#include <android/versioning.h>
-
-#include <android/versioning.h>
-
#define __always_inline __attribute__((__always_inline__))
#define __attribute_const__ __attribute__((__const__))
#define __attribute_pure__ __attribute__((__pure__))
@@ -359,4 +334,5 @@
*/
#define __unsafe_check_mul_overflow(x, y) ((__SIZE_TYPE__)-1 / (x) < (y))
-#endif /* !_SYS_CDEFS_H_ */
+#include <android/versioning.h>
+#include <android/api-level.h>
diff --git a/libc/private/bionic_constants.h b/libc/private/bionic_constants.h
index 9ae1c8d..e64c826 100644
--- a/libc/private/bionic_constants.h
+++ b/libc/private/bionic_constants.h
@@ -19,4 +19,14 @@
#define NS_PER_S 1000000000
+// Size of the shadow call stack. This must be a power of 2.
+#define SCS_SIZE (8 * 1024)
+
+// The shadow call stack is allocated at an aligned address within a guard region of this size. The
+// guard region must be large enough that we can allocate an SCS_SIZE-aligned SCS while ensuring
+// that there is at least one guard page after the SCS so that a stack overflow results in a SIGSEGV
+// instead of corrupting the allocation that comes after it.
+// TODO(b/118642754): Use a larger guard region.
+#define SCS_GUARD_REGION_SIZE (SCS_SIZE * 2)
+
#endif // _BIONIC_CONSTANTS_H_
diff --git a/libc/private/bionic_sdk_version.h b/libc/private/bionic_sdk_version.h
deleted file mode 100644
index b352d9a..0000000
--- a/libc/private/bionic_sdk_version.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _BIONIC_SDK_VERSION_H_
-#define _BIONIC_SDK_VERSION_H_
-
-#include <stdint.h>
-
-int bionic_get_application_target_sdk_version();
-
-#endif // _BIONIC_SDK_VERSION_H_
diff --git a/libdl/libdl.arm.map b/libdl/libdl.arm.map
index 1fcfc58..28f0601 100644
--- a/libdl/libdl.arm.map
+++ b/libdl/libdl.arm.map
@@ -31,6 +31,7 @@
LIBC_N {
global:
+ android_get_application_target_sdk_version; # introduced=24 versioned=29
dlvsym; # introduced=24
} LIBC;
@@ -45,7 +46,6 @@
global:
__cfi_init;
android_dlwarning;
- android_get_application_target_sdk_version;
android_set_application_target_sdk_version;
android_get_LD_LIBRARY_PATH;
android_update_LD_LIBRARY_PATH;
diff --git a/libdl/libdl.arm64.map b/libdl/libdl.arm64.map
index 8d4019c..a03e9e1 100644
--- a/libdl/libdl.arm64.map
+++ b/libdl/libdl.arm64.map
@@ -30,6 +30,7 @@
LIBC_N {
global:
+ android_get_application_target_sdk_version; # introduced=24 versioned=29
dlvsym; # introduced=24
} LIBC;
@@ -44,7 +45,6 @@
global:
__cfi_init;
android_dlwarning;
- android_get_application_target_sdk_version;
android_set_application_target_sdk_version;
android_get_LD_LIBRARY_PATH;
android_update_LD_LIBRARY_PATH;
diff --git a/libdl/libdl.map.txt b/libdl/libdl.map.txt
index 002e9f8..c5d1be4 100644
--- a/libdl/libdl.map.txt
+++ b/libdl/libdl.map.txt
@@ -30,6 +30,7 @@
LIBC_N {
global:
+ android_get_application_target_sdk_version; # introduced=24 versioned=29
dlvsym; # introduced=24
} LIBC;
@@ -44,7 +45,6 @@
global:
__cfi_init;
android_dlwarning;
- android_get_application_target_sdk_version;
android_set_application_target_sdk_version;
android_get_LD_LIBRARY_PATH;
android_update_LD_LIBRARY_PATH;
diff --git a/libdl/libdl.mips.map b/libdl/libdl.mips.map
index 8d4019c..a03e9e1 100644
--- a/libdl/libdl.mips.map
+++ b/libdl/libdl.mips.map
@@ -30,6 +30,7 @@
LIBC_N {
global:
+ android_get_application_target_sdk_version; # introduced=24 versioned=29
dlvsym; # introduced=24
} LIBC;
@@ -44,7 +45,6 @@
global:
__cfi_init;
android_dlwarning;
- android_get_application_target_sdk_version;
android_set_application_target_sdk_version;
android_get_LD_LIBRARY_PATH;
android_update_LD_LIBRARY_PATH;
diff --git a/libdl/libdl.mips64.map b/libdl/libdl.mips64.map
index 8d4019c..a03e9e1 100644
--- a/libdl/libdl.mips64.map
+++ b/libdl/libdl.mips64.map
@@ -30,6 +30,7 @@
LIBC_N {
global:
+ android_get_application_target_sdk_version; # introduced=24 versioned=29
dlvsym; # introduced=24
} LIBC;
@@ -44,7 +45,6 @@
global:
__cfi_init;
android_dlwarning;
- android_get_application_target_sdk_version;
android_set_application_target_sdk_version;
android_get_LD_LIBRARY_PATH;
android_update_LD_LIBRARY_PATH;
diff --git a/libdl/libdl.x86.map b/libdl/libdl.x86.map
index 8d4019c..a03e9e1 100644
--- a/libdl/libdl.x86.map
+++ b/libdl/libdl.x86.map
@@ -30,6 +30,7 @@
LIBC_N {
global:
+ android_get_application_target_sdk_version; # introduced=24 versioned=29
dlvsym; # introduced=24
} LIBC;
@@ -44,7 +45,6 @@
global:
__cfi_init;
android_dlwarning;
- android_get_application_target_sdk_version;
android_set_application_target_sdk_version;
android_get_LD_LIBRARY_PATH;
android_update_LD_LIBRARY_PATH;
diff --git a/libdl/libdl.x86_64.map b/libdl/libdl.x86_64.map
index 8d4019c..a03e9e1 100644
--- a/libdl/libdl.x86_64.map
+++ b/libdl/libdl.x86_64.map
@@ -30,6 +30,7 @@
LIBC_N {
global:
+ android_get_application_target_sdk_version; # introduced=24 versioned=29
dlvsym; # introduced=24
} LIBC;
@@ -44,7 +45,6 @@
global:
__cfi_init;
android_dlwarning;
- android_get_application_target_sdk_version;
android_set_application_target_sdk_version;
android_get_LD_LIBRARY_PATH;
android_update_LD_LIBRARY_PATH;
diff --git a/linker/linker_utils.cpp b/linker/linker_utils.cpp
index 6b9aec9..d08b161 100644
--- a/linker/linker_utils.cpp
+++ b/linker/linker_utils.cpp
@@ -235,6 +235,13 @@
}
resolved_paths->push_back(std::string(resolved_path) + kZipFileSeparator + entry_path);
+ } else {
+ struct stat s;
+ if (stat(normalized_path.c_str(), &s) == 0 && S_ISDIR(s.st_mode)) {
+ // Path is not a zip path, but an existing directory. Then add it
+ // although we failed to resolve it. b/119656753
+ resolved_paths->push_back(normalized_path);
+ }
}
}
}
diff --git a/tests/Android.bp b/tests/Android.bp
index 6a644b6..899fc66 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -121,6 +121,7 @@
"regex_test.cpp",
"resolv_test.cpp",
"sched_test.cpp",
+ "scs_test.cpp",
"scsi_sg_test.cpp",
"search_test.cpp",
"semaphore_test.cpp",
diff --git a/tests/android_get_device_api_level.cpp b/tests/android_get_device_api_level.cpp
index 5272a48..0662404 100644
--- a/tests/android_get_device_api_level.cpp
+++ b/tests/android_get_device_api_level.cpp
@@ -29,7 +29,7 @@
#include <gtest/gtest.h>
#if __BIONIC__
-#include <android/get_device_api_level.h>
+#include <android/api-level.h>
#endif
TEST(android_get_device_api_level, smoke) {
diff --git a/tests/libdl_test.cpp b/tests/libdl_test.cpp
index 0c2bf67..6774f1d 100644
--- a/tests/libdl_test.cpp
+++ b/tests/libdl_test.cpp
@@ -18,7 +18,6 @@
#include <android/api-level.h>
-extern "C" int android_get_application_target_sdk_version();
extern "C" void android_set_application_target_sdk_version(int target);
TEST(libdl, application_sdk_versions_smoke) {
diff --git a/tests/scs_test.cpp b/tests/scs_test.cpp
new file mode 100644
index 0000000..24cb347
--- /dev/null
+++ b/tests/scs_test.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#if __has_feature(shadow_call_stack)
+
+#include <gtest/gtest.h>
+
+#include "private/bionic_constants.h"
+
+int recurse2(int count);
+
+__attribute__((weak, noinline)) int recurse1(int count) {
+ if (count != 0) return recurse2(count - 1) + 1;
+ return 0;
+}
+
+__attribute__((weak, noinline)) int recurse2(int count) {
+ if (count != 0) return recurse1(count - 1) + 1;
+ return 0;
+}
+
+TEST(scs_test, stack_overflow) {
+ ASSERT_EXIT(recurse1(SCS_SIZE), testing::KilledBySignal(SIGSEGV), "");
+}
+
+#endif
diff --git a/tests/setjmp_test.cpp b/tests/setjmp_test.cpp
index dde0be1..44d8af1 100644
--- a/tests/setjmp_test.cpp
+++ b/tests/setjmp_test.cpp
@@ -264,3 +264,14 @@
fprintf(stderr, "setjmp_cookie_checksum: longjmp succeeded?");
}
}
+
+__attribute__((noinline)) void call_longjmp(jmp_buf buf) {
+ longjmp(buf, 123);
+}
+
+TEST(setjmp, setjmp_stack) {
+ jmp_buf buf;
+ int value = setjmp(buf);
+ if (value == 0) call_longjmp(buf);
+ EXPECT_EQ(123, value);
+}