aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libc/Android.bp211
-rw-r--r--libc/arch-arm/cortex-a15/bionic/memcpy.S4
-rw-r--r--libc/arch-arm/cortex-a15/bionic/memmove.S32
-rw-r--r--libc/arch-arm/cortex-a15/bionic/memset.S8
-rw-r--r--libc/arch-arm/cortex-a15/bionic/strcat.S4
-rw-r--r--libc/arch-arm/cortex-a15/bionic/strcmp.S4
-rw-r--r--libc/arch-arm/cortex-a15/bionic/string_copy.S8
-rw-r--r--libc/arch-arm/cortex-a15/bionic/strlen.S4
-rw-r--r--libc/arch-arm/cortex-a53/bionic/memcpy.S4
-rw-r--r--libc/arch-arm/cortex-a53/bionic/memmove.S32
-rw-r--r--libc/arch-arm/cortex-a7/bionic/memcpy.S4
-rw-r--r--libc/arch-arm/cortex-a7/bionic/memmove.S32
-rw-r--r--libc/arch-arm/cortex-a7/bionic/memset.S8
-rw-r--r--libc/arch-arm/cortex-a9/bionic/memcpy.S8
-rw-r--r--libc/arch-arm/cortex-a9/bionic/memcpy_base.S6
-rw-r--r--libc/arch-arm/cortex-a9/bionic/memmove.S32
-rw-r--r--libc/arch-arm/cortex-a9/bionic/memset.S8
-rw-r--r--libc/arch-arm/cortex-a9/bionic/strcat.S8
-rw-r--r--libc/arch-arm/cortex-a9/bionic/strcmp.S8
-rw-r--r--libc/arch-arm/cortex-a9/bionic/string_copy.S12
-rw-r--r--libc/arch-arm/cortex-a9/bionic/strlen.S8
-rw-r--r--libc/arch-arm/denver/bionic/memcpy.S8
-rw-r--r--libc/arch-arm/denver/bionic/memmove.S16
-rw-r--r--libc/arch-arm/denver/bionic/memset.S8
-rw-r--r--libc/arch-arm/dynamic_function_dispatch.cpp267
-rw-r--r--libc/arch-arm/generic/bionic/memmove.S6
-rw-r--r--libc/arch-arm/generic/bionic/memset.S8
-rw-r--r--libc/arch-arm/generic/bionic/stpcpy.c30
-rw-r--r--libc/arch-arm/generic/bionic/strcat.c30
-rw-r--r--libc/arch-arm/generic/bionic/strcmp.S8
-rw-r--r--libc/arch-arm/generic/bionic/strcpy.S8
-rw-r--r--libc/arch-arm/generic/bionic/strlen.c2
-rw-r--r--libc/arch-arm/krait/bionic/memcpy.S4
-rw-r--r--libc/arch-arm/krait/bionic/memcpy_base.S5
-rw-r--r--libc/arch-arm/krait/bionic/memmove.S32
-rw-r--r--libc/arch-arm/krait/bionic/memset.S8
-rw-r--r--libc/arch-arm/krait/bionic/strcmp.S8
-rw-r--r--libc/arch-arm/kryo/bionic/memcpy.S10
-rw-r--r--libc/arch-arm/kryo/bionic/memmove.S32
-rw-r--r--libc/arch-arm/static_function_dispatch.S44
-rw-r--r--libc/bionic/NetdClient.cpp2
-rw-r--r--libc/bionic/NetdClientDispatch.cpp5
-rw-r--r--libc/bionic/libc_init_common.cpp21
-rw-r--r--libc/bionic/libc_init_dynamic.cpp7
-rw-r--r--libc/bionic/malloc_common.cpp18
-rw-r--r--libc/dns/include/resolv_netid.h1
-rw-r--r--libc/dns/net/getaddrinfo.c3
-rw-r--r--libc/dns/net/gethnamaddr.c35
-rw-r--r--libc/include/paths.h2
-rw-r--r--libc/private/NetdClientDispatch.h1
-rw-r--r--libm/Android.bp3
-rw-r--r--linker/Android.bp1
-rw-r--r--linker/linker.cpp4
-rw-r--r--linker/linker_allocator.cpp2
-rw-r--r--linker/linker_main.cpp8
-rw-r--r--linker/linker_utils.cpp7
-rw-r--r--tests/malloc_test.cpp41
57 files changed, 832 insertions, 308 deletions
diff --git a/libc/Android.bp b/libc/Android.bp
index 4adb51350..b7965c874 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -76,6 +76,9 @@ cc_defaults {
},
native_coverage: false,
recovery_available: true,
+
+ // TODO(ivanlozano): Remove after b/118321713
+ xom: false,
}
// ANDROIDMK TRANSLATION ERROR: unsupported directive
@@ -551,13 +554,9 @@ cc_library_static {
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 +848,8 @@ cc_library_static {
"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 +863,44 @@ cc_library_static {
"arch-arm/bionic/setjmp.S",
"arch-arm/bionic/syscall.S",
"arch-arm/bionic/vfork.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",
- ],
- },
+ "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",
+ ],
},
arm64: {
srcs: [
@@ -1634,6 +1517,9 @@ cc_library_static {
x86: {
srcs: ["arch-x86/static_function_dispatch.S"],
},
+ arm: {
+ srcs: ["arch-arm/static_function_dispatch.S"],
+ },
},
whole_static_libs: [
@@ -1656,6 +1542,9 @@ cc_library_static {
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 0bab6ee7d..a9dfaff0f 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 @@ ENTRY(__memcpy)
.cfi_rel_offset lr, 4
#include "memcpy_base.S"
-END(__memcpy)
+END(__memcpy_a15)
diff --git a/libc/arch-arm/cortex-a15/bionic/memmove.S b/libc/arch-arm/cortex-a15/bionic/memmove.S
new file mode 100644
index 000000000..2b12de006
--- /dev/null
+++ b/libc/arch-arm/cortex-a15/bionic/memmove.S
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+#define MEMMOVE memmove_a15
+#define MEMCPY __memcpy_a15
+
+#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 4b4388e2e..ead881e49 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 @@ ENTRY(__memset_chk)
.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 @@ ENTRY(memset)
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 157cc9f1d..260926a0a 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 @@ ENTRY(strcat)
.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 d8993d55f..58dbf170e 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 @@ ENTRY(strcmp)
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 92d1c9804..affbc3b20 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 @@ ENTRY(strcpy)
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 4fd62842c..9c5ed2911 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 @@ ENTRY(strlen)
.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 0bab6ee7d..ea748bd00 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 @@ ENTRY(__memcpy)
.cfi_rel_offset lr, 4
#include "memcpy_base.S"
-END(__memcpy)
+END(__memcpy_a53)
diff --git a/libc/arch-arm/cortex-a53/bionic/memmove.S b/libc/arch-arm/cortex-a53/bionic/memmove.S
new file mode 100644
index 000000000..741acb394
--- /dev/null
+++ b/libc/arch-arm/cortex-a53/bionic/memmove.S
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+#define MEMMOVE memmove_a53
+#define MEMCPY __memcpy_a53
+
+#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 0bab6ee7d..2f32d2e7e 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 @@ ENTRY(__memcpy)
.cfi_rel_offset lr, 4
#include "memcpy_base.S"
-END(__memcpy)
+END(__memcpy_a7)
diff --git a/libc/arch-arm/cortex-a7/bionic/memmove.S b/libc/arch-arm/cortex-a7/bionic/memmove.S
new file mode 100644
index 000000000..17ead5a15
--- /dev/null
+++ b/libc/arch-arm/cortex-a7/bionic/memmove.S
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+#define MEMMOVE memmove_a7
+#define MEMCPY __memcpy_a7
+
+#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 72ee61363..d7d3b34e0 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 @@ ENTRY(__memset_chk)
.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 @@ ENTRY(memset)
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 a71c9d21c..e78a7daa9 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 966b9b3c0..39da7ffcf 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/arch-arm/cortex-a9/bionic/memmove.S b/libc/arch-arm/cortex-a9/bionic/memmove.S
new file mode 100644
index 000000000..a45763372
--- /dev/null
+++ b/libc/arch-arm/cortex-a9/bionic/memmove.S
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+#define MEMMOVE memmove_a9
+#define MEMCPY __memcpy_a9
+
+#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 d00231bdc..cf66e86c9 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 @@ ENTRY(__memset_chk)
.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 @@ ENTRY(memset)
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 9077a7449..430748f25 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 @@ ENTRY(strcat)
.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 ba191d60b..ba7ea13a3 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 @@ ENTRY(strcmp)
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 642db0f19..3605b7a57 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 @@ ENTRY(strcpy)
#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 b92b04352..ffebc9dea 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 @@ done:
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 f0825421e..5edee1e31 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 74d2b31bc..13c90efc1 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 @@ ENTRY(memmove)
bhi .L_reversed_memcpy
.L_jump_to_memcpy:
- b __memcpy
+ b MEMCPY
.L_reversed_memcpy:
push {r0, lr}
@@ -277,6 +285,4 @@ ENTRY(memmove)
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 88ffe5c4f..198ecf3ec 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 @@ ENTRY(__memset_chk)
.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 @@ ENTRY(memset)
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 000000000..17f00876b
--- /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 c52e17ed5..0cf82d14f 100644
--- a/libc/arch-arm/generic/bionic/memmove.S
+++ b/libc/arch-arm/generic/bionic/memmove.S
@@ -464,10 +464,8 @@ ENTRY_PRIVATE(bsd_safe_memcpy)
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 1fd0de1db..e70002f02 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 @@ ENTRY(memset)
movs r2, r2, lsl #2
strbcs r1, [r0]
ldmfd sp!, {r0, r4-r7, pc}
-END(memset)
+END(memset_generic)
diff --git a/libc/arch-arm/generic/bionic/stpcpy.c b/libc/arch-arm/generic/bionic/stpcpy.c
new file mode 100644
index 000000000..0aabaa5da
--- /dev/null
+++ b/libc/arch-arm/generic/bionic/stpcpy.c
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+#define stpcpy stpcpy_generic
+#include <upstream-openbsd/lib/libc/string/stpcpy.c>
diff --git a/libc/arch-arm/generic/bionic/strcat.c b/libc/arch-arm/generic/bionic/strcat.c
new file mode 100644
index 000000000..8e70531d0
--- /dev/null
+++ b/libc/arch-arm/generic/bionic/strcat.c
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+#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 10b670422..03225a006 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 @@ ENTRY(strcmp)
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 c0ab9e5dc..89bd69913 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 @@ ENTRY(strcpy)
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 44bd72ff5..43d9e514c 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 49fd04069..6618b3ad0 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 @@ ENTRY(__memcpy)
.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 dc8ad2cdf..5b4b70d5c 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/arch-arm/krait/bionic/memmove.S b/libc/arch-arm/krait/bionic/memmove.S
new file mode 100644
index 000000000..af85ea62e
--- /dev/null
+++ b/libc/arch-arm/krait/bionic/memmove.S
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+#define MEMMOVE memmove_krait
+#define MEMCPY __memcpy_krait
+
+#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 228942cbe..675ab53bc 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 @@ ENTRY(__memset_chk)
.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 @@ ENTRY(memset)
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 b871c7622..ec692e524 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 @@ ENTRY(strcmp)
.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 74036ef3a..250f7bc61 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 @@ ENTRY(__memcpy)
pop {r0}
bx lr
-END(__memcpy)
+END(__memcpy_kryo)
diff --git a/libc/arch-arm/kryo/bionic/memmove.S b/libc/arch-arm/kryo/bionic/memmove.S
new file mode 100644
index 000000000..d0fdd8fa9
--- /dev/null
+++ b/libc/arch-arm/kryo/bionic/memmove.S
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+#define MEMMOVE memmove_kryo
+#define MEMCPY __memcpy_kryo
+
+#include <arch-arm/denver/bionic/memmove.S>
diff --git a/libc/arch-arm/static_function_dispatch.S b/libc/arch-arm/static_function_dispatch.S
new file mode 100644
index 000000000..f3dd741f9
--- /dev/null
+++ b/libc/arch-arm/static_function_dispatch.S
@@ -0,0 +1,44 @@
+/*
+ * 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 <private/bionic_asm.h>
+
+#define FUNCTION_DELEGATE(name, impl) \
+ENTRY(name); \
+ b impl; \
+END(name)
+
+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/bionic/NetdClient.cpp b/libc/bionic/NetdClient.cpp
index a5c519eee..87eec27b5 100644
--- a/libc/bionic/NetdClient.cpp
+++ b/libc/bionic/NetdClient.cpp
@@ -58,6 +58,8 @@ static void netdClientInitImpl() {
netdClientInitFunction(netdClientHandle, "netdClientInitNetIdForResolv",
&__netdClientDispatch.netIdForResolv);
netdClientInitFunction(netdClientHandle, "netdClientInitSocket", &__netdClientDispatch.socket);
+ netdClientInitFunction(netdClientHandle, "netdClientInitDnsOpenProxy",
+ &__netdClientDispatch.dnsOpenProxy);
}
static pthread_once_t netdClientInitOnce = PTHREAD_ONCE_INIT;
diff --git a/libc/bionic/NetdClientDispatch.cpp b/libc/bionic/NetdClientDispatch.cpp
index 67fa1976f..a8731730f 100644
--- a/libc/bionic/NetdClientDispatch.cpp
+++ b/libc/bionic/NetdClientDispatch.cpp
@@ -30,6 +30,10 @@ static unsigned fallBackNetIdForResolv(unsigned netId) {
return netId;
}
+static int fallBackDnsOpenProxy() {
+ return -1;
+}
+
// This structure is modified only at startup (when libc.so is loaded) and never
// afterwards, so it's okay that it's read later at runtime without a lock.
__LIBC_HIDDEN__ NetdClientDispatch __netdClientDispatch __attribute__((aligned(32))) = {
@@ -37,4 +41,5 @@ __LIBC_HIDDEN__ NetdClientDispatch __netdClientDispatch __attribute__((aligned(3
__connect,
__socket,
fallBackNetIdForResolv,
+ fallBackDnsOpenProxy,
};
diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp
index f943402bc..a860b98dd 100644
--- a/libc/bionic/libc_init_common.cpp
+++ b/libc/bionic/libc_init_common.cpp
@@ -62,13 +62,9 @@ __LIBC_HIDDEN__ libc_shared_globals* __libc_shared_globals;
const char* __progname;
void __libc_init_globals(KernelArgumentBlock& args) {
-#if defined(__i386__)
- __libc_init_sysinfo(args);
-#endif
// Initialize libc globals that are needed in both the linker and in libc.
// In dynamic binaries, this is run at least twice for different copies of the
// globals, once for the linker's copy and once for the one in libc.so.
- __libc_auxv = args.auxv;
__libc_globals.initialize();
__libc_globals.mutate([&args](libc_globals* globals) {
__libc_init_vdso(globals, args);
@@ -275,7 +271,6 @@ static bool __is_unsafe_environment_variable(const char* name) {
}
static void __sanitize_environment_variables(char** env) {
- bool is_AT_SECURE = getauxval(AT_SECURE);
char** src = env;
char** dst = env;
for (; src[0] != nullptr; ++src) {
@@ -283,7 +278,7 @@ static void __sanitize_environment_variables(char** env) {
continue;
}
// Remove various unsafe environment variables if we're loading a setuid program.
- if (is_AT_SECURE && __is_unsafe_environment_variable(src[0])) {
+ if (__is_unsafe_environment_variable(src[0])) {
continue;
}
dst[0] = src[0];
@@ -306,20 +301,14 @@ static void __initialize_personality() {
}
void __libc_init_AT_SECURE(KernelArgumentBlock& args) {
- __libc_auxv = args.auxv;
__abort_message_ptr = args.abort_message_ptr;
// Check that the kernel provided a value for AT_SECURE.
- bool found_AT_SECURE = false;
- for (ElfW(auxv_t)* v = __libc_auxv; v->a_type != AT_NULL; ++v) {
- if (v->a_type == AT_SECURE) {
- found_AT_SECURE = true;
- break;
- }
- }
- if (!found_AT_SECURE) __early_abort(__LINE__);
+ errno = 0;
+ unsigned long is_AT_SECURE = getauxval(AT_SECURE);
+ if (errno != 0) __early_abort(__LINE__);
- if (getauxval(AT_SECURE)) {
+ if (is_AT_SECURE) {
// If this is a setuid/setgid program, close the security hole described in
// https://www.freebsd.org/security/advisories/FreeBSD-SA-02:23.stdio.asc
__nullify_closed_stdio();
diff --git a/libc/bionic/libc_init_dynamic.cpp b/libc/bionic/libc_init_dynamic.cpp
index fc68b8a2f..08d3df4ff 100644
--- a/libc/bionic/libc_init_dynamic.cpp
+++ b/libc/bionic/libc_init_dynamic.cpp
@@ -51,6 +51,7 @@
#include <elf.h>
#include "libc_init_common.h"
+#include "private/bionic_auxv.h"
#include "private/bionic_globals.h"
#include "private/bionic_macros.h"
#include "private/bionic_ssp.h"
@@ -78,8 +79,12 @@ __LIBC_HIDDEN__ void* __libc_sysinfo = reinterpret_cast<void*>(__libc_int0x80);
// protector.
__attribute__((noinline))
static void __libc_preinit_impl(KernelArgumentBlock& args) {
- __libc_shared_globals = args.shared_globals;
+ __libc_auxv = args.auxv;
+#if defined(__i386__)
+ __libc_init_sysinfo(args);
+#endif
+ __libc_shared_globals = args.shared_globals;
__libc_init_globals(args);
__libc_init_common(args);
diff --git a/libc/bionic/malloc_common.cpp b/libc/bionic/malloc_common.cpp
index 8d8d4207d..9a8076784 100644
--- a/libc/bionic/malloc_common.cpp
+++ b/libc/bionic/malloc_common.cpp
@@ -366,12 +366,6 @@ static bool InitMallocFunction(void* malloc_impl_handler, _Atomic(FunctionType)*
}
static bool InitMallocFunctions(void* impl_handler, MallocDispatch* table, const char* prefix) {
- // We initialize free first to prevent the following situation:
- // Heapprofd's MallocMalloc is installed, and an allocation is observed
- // and logged to the heap dump. The corresponding free happens before
- // heapprofd's MallocFree is installed, and is not logged in the heap
- // dump. This leads to the allocation wrongly being active in the heap
- // dump indefinitely.
if (!InitMallocFunction<MallocFree>(impl_handler, &table->free, prefix, "free")) {
return false;
}
@@ -572,6 +566,16 @@ static void install_hooks(libc_globals* globals, const char* options,
}
atomic_store(&g_heapprofd_init_func, init_func);
+ // We assign free first explicitly to prevent the case where we observe a
+ // alloc, but miss the corresponding free because of initialization order.
+ //
+ // This is safer than relying on the declaration order inside
+ // MallocDispatch at the cost of an extra atomic pointer write on
+ // initialization.
+ atomic_store(&globals->malloc_dispatch.free, dispatch_table.free);
+ // The struct gets assigned elementwise and each of the elements is an
+ // _Atomic. Assigning to an _Atomic is an atomic_store operation.
+ // The assignment is done in declaration order.
globals->malloc_dispatch = dispatch_table;
info_log("%s: malloc %s enabled", getprogname(), prefix);
@@ -679,7 +683,7 @@ static void* InitHeapprofdHook(size_t bytes) {
extern "C" void InstallInitHeapprofdHook(int) {
if (!atomic_exchange(&g_heapprofd_init_in_progress, true)) {
__libc_globals.mutate([](libc_globals* globals) {
- globals->malloc_dispatch.malloc = InitHeapprofdHook;
+ atomic_store(&globals->malloc_dispatch.malloc, InitHeapprofdHook);
});
}
}
diff --git a/libc/dns/include/resolv_netid.h b/libc/dns/include/resolv_netid.h
index c7e2823d8..aa3159601 100644
--- a/libc/dns/include/resolv_netid.h
+++ b/libc/dns/include/resolv_netid.h
@@ -107,7 +107,6 @@ extern void _resolv_delete_cache_for_net(unsigned netid) __used_in_netd;
/* Internal use only. */
struct hostent *android_gethostbyaddrfornetcontext_proxy(const void *, socklen_t, int , const struct android_net_context *) __LIBC_HIDDEN__;
int android_getnameinfofornet(const struct sockaddr *, socklen_t, char *, size_t, char *, size_t, int, unsigned, unsigned) __LIBC_HIDDEN__;
-FILE* android_open_proxy(void) __LIBC_HIDDEN__;
__END_DECLS
diff --git a/libc/dns/net/getaddrinfo.c b/libc/dns/net/getaddrinfo.c
index f1488a93f..4e1aa61d5 100644
--- a/libc/dns/net/getaddrinfo.c
+++ b/libc/dns/net/getaddrinfo.c
@@ -422,11 +422,10 @@ android_getaddrinfo_proxy(
return EAI_NODATA;
}
- FILE* proxy = android_open_proxy();
+ FILE* proxy = fdopen(__netdClientDispatch.dnsOpenProxy(), "r+");
if (proxy == NULL) {
return EAI_SYSTEM;
}
-
netid = __netdClientDispatch.netIdForResolv(netid);
// Send the request.
diff --git a/libc/dns/net/gethnamaddr.c b/libc/dns/net/gethnamaddr.c
index 758938081..7e18840d4 100644
--- a/libc/dns/net/gethnamaddr.c
+++ b/libc/dns/net/gethnamaddr.c
@@ -565,34 +565,6 @@ gethostbyname2_r(const char *name, int af, struct hostent *hp, char *buf,
return h_errno_to_result(errorp);
}
-__LIBC_HIDDEN__ FILE* android_open_proxy() {
- const char* cache_mode = getenv("ANDROID_DNS_MODE");
- bool use_proxy = (cache_mode == NULL || strcmp(cache_mode, "local") != 0);
- if (!use_proxy) {
- return NULL;
- }
-
- int s = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
- if (s == -1) {
- return NULL;
- }
-
- const int one = 1;
- setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
-
- struct sockaddr_un proxy_addr;
- memset(&proxy_addr, 0, sizeof(proxy_addr));
- proxy_addr.sun_family = AF_UNIX;
- strlcpy(proxy_addr.sun_path, "/dev/socket/dnsproxyd", sizeof(proxy_addr.sun_path));
-
- if (TEMP_FAILURE_RETRY(connect(s, (const struct sockaddr*) &proxy_addr, sizeof(proxy_addr))) != 0) {
- close(s);
- return NULL;
- }
-
- return fdopen(s, "r+");
-}
-
static struct hostent *
android_read_hostent(FILE* proxy, struct hostent* hp, char* hbuf, size_t hbuflen, int *he)
{
@@ -816,18 +788,16 @@ fake:
return hp;
}
-// very similar in proxy-ness to android_getaddrinfo_proxy
static struct hostent *
gethostbyname_internal(const char *name, int af, res_state res, struct hostent *hp, char *hbuf,
size_t hbuflen, int *errorp, const struct android_net_context *netcontext)
{
- FILE* proxy = android_open_proxy();
+ FILE* proxy = fdopen(__netdClientDispatch.dnsOpenProxy(), "r+");
if (proxy == NULL) {
// Either we're not supposed to be using the proxy or the proxy is unavailable.
res_setnetcontext(res, netcontext);
return gethostbyname_internal_real(name, af, res, hp, hbuf, hbuflen, errorp);
}
-
unsigned netid = __netdClientDispatch.netIdForResolv(netcontext->app_netid);
// This is writing to system/netd/server/DnsProxyListener.cpp and changes
@@ -925,12 +895,11 @@ android_gethostbyaddrfornetcontext_proxy_internal(const void* addr, socklen_t le
struct hostent *hp, char *hbuf, size_t hbuflen, int *he,
const struct android_net_context *netcontext)
{
- FILE* proxy = android_open_proxy();
+ FILE* proxy = fdopen(__netdClientDispatch.dnsOpenProxy(), "r+");
if (proxy == NULL) {
// Either we're not supposed to be using the proxy or the proxy is unavailable.
return android_gethostbyaddrfornetcontext_real(addr,len, af, hp, hbuf, hbuflen, he, netcontext);
}
-
char buf[INET6_ADDRSTRLEN]; //big enough for IPv4 and IPv6
const char * addrStr = inet_ntop(af, addr, buf, sizeof(buf));
if (addrStr == NULL) {
diff --git a/libc/include/paths.h b/libc/include/paths.h
index b5b86101c..dc1c52351 100644
--- a/libc/include/paths.h
+++ b/libc/include/paths.h
@@ -47,7 +47,7 @@
#define _PATH_CONSOLE "/dev/console"
/** Default shell search path. */
-#define _PATH_DEFPATH "/sbin:/system/sbin:/apex/com.android.runtime/bin:/system/bin:/system/xbin:/odm/bin:/vendor/bin:/vendor/xbin"
+#define _PATH_DEFPATH "/sbin:/system/sbin:/system/bin:/system/xbin:/odm/bin:/vendor/bin:/vendor/xbin"
/** Path to the directory containing device files. */
#define _PATH_DEV "/dev/"
diff --git a/libc/private/NetdClientDispatch.h b/libc/private/NetdClientDispatch.h
index 8d8947dcc..20e7f25b7 100644
--- a/libc/private/NetdClientDispatch.h
+++ b/libc/private/NetdClientDispatch.h
@@ -27,6 +27,7 @@ struct NetdClientDispatch {
int (*connect)(int, const struct sockaddr*, socklen_t);
int (*socket)(int, int, int);
unsigned (*netIdForResolv)(unsigned);
+ int (*dnsOpenProxy)();
};
extern __LIBC_HIDDEN__ struct NetdClientDispatch __netdClientDispatch;
diff --git a/libm/Android.bp b/libm/Android.bp
index 6d55967ca..e4ba20d92 100644
--- a/libm/Android.bp
+++ b/libm/Android.bp
@@ -514,6 +514,9 @@ cc_library {
integer_overflow: false,
},
stl: "none",
+
+ // TODO(ivanlozano): Remove after b/118321713
+ xom: false,
}
ndk_library {
diff --git a/linker/Android.bp b/linker/Android.bp
index 8ef540c37..a9907ca44 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -289,6 +289,7 @@ cc_binary {
},
},
compile_multilib: "both",
+ xom: false,
}
cc_library {
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 3560b4e63..7993681d3 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -89,7 +89,6 @@ static const char* const kLdConfigFilePath = "/system/etc/ld.config.txt";
static const char* const kLdConfigVndkLiteFilePath = "/system/etc/ld.config.vndk_lite.txt";
#if defined(__LP64__)
-static const char* const kArtApexLibDir = "/apex/com.android.runtime/lib64";
static const char* const kSystemLibDir = "/system/lib64";
static const char* const kOdmLibDir = "/odm/lib64";
static const char* const kVendorLibDir = "/vendor/lib64";
@@ -97,7 +96,6 @@ static const char* const kAsanSystemLibDir = "/data/asan/system/lib64";
static const char* const kAsanOdmLibDir = "/data/asan/odm/lib64";
static const char* const kAsanVendorLibDir = "/data/asan/vendor/lib64";
#else
-static const char* const kArtApexLibDir = "/apex/com.android.runtime/lib";
static const char* const kSystemLibDir = "/system/lib";
static const char* const kOdmLibDir = "/odm/lib";
static const char* const kVendorLibDir = "/vendor/lib";
@@ -109,7 +107,6 @@ static const char* const kAsanVendorLibDir = "/data/asan/vendor/lib";
static const char* const kAsanLibDirPrefix = "/data/asan";
static const char* const kDefaultLdPaths[] = {
- kArtApexLibDir,
kSystemLibDir,
kOdmLibDir,
kVendorLibDir,
@@ -118,7 +115,6 @@ static const char* const kDefaultLdPaths[] = {
static const char* const kAsanDefaultLdPaths[] = {
kAsanSystemLibDir,
- kArtApexLibDir,
kSystemLibDir,
kAsanOdmLibDir,
kOdmLibDir,
diff --git a/linker/linker_allocator.cpp b/linker/linker_allocator.cpp
index de3309bd5..8b05a7e65 100644
--- a/linker/linker_allocator.cpp
+++ b/linker/linker_allocator.cpp
@@ -222,6 +222,8 @@ void LinkerSmallObjectAllocator::alloc_page() {
first_block->free_blocks_cnt = free_blocks_cnt;
free_blocks_list_ = first_block;
+
+ free_pages_cnt_++;
}
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index f7c496a25..66766fe56 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -28,6 +28,9 @@
#include "linker_main.h"
+#include <link.h>
+#include <sys/auxv.h>
+
#include "linker_debug.h"
#include "linker_cfi.h"
#include "linker_gdb_support.h"
@@ -35,7 +38,6 @@
#include "linker_phdr.h"
#include "linker_utils.h"
-#include "private/bionic_auxv.h"
#include "private/bionic_globals.h"
#include "private/bionic_tls.h"
#include "private/KernelArgumentBlock.h"
@@ -48,12 +50,10 @@
#endif
#include <async_safe/log.h>
+#include <bionic/libc_init_common.h>
#include <vector>
-extern void __libc_init_globals(KernelArgumentBlock&);
-extern void __libc_init_AT_SECURE(KernelArgumentBlock&);
-
__LIBC_HIDDEN__ extern "C" void _start();
static ElfW(Addr) get_elf_exec_load_bias(const ElfW(Ehdr)* elf);
diff --git a/linker/linker_utils.cpp b/linker/linker_utils.cpp
index 6b9aec9fa..d08b161ca 100644
--- a/linker/linker_utils.cpp
+++ b/linker/linker_utils.cpp
@@ -235,6 +235,13 @@ void resolve_paths(std::vector<std::string>& paths,
}
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/malloc_test.cpp b/tests/malloc_test.cpp
index 8b670f0e5..4a012786d 100644
--- a/tests/malloc_test.cpp
+++ b/tests/malloc_test.cpp
@@ -560,3 +560,44 @@ TEST(malloc, reallocarray) {
GTEST_LOG_(INFO) << "This test requires a C library with reallocarray.\n";
#endif
}
+
+TEST(malloc, mallinfo) {
+#if defined(__BIONIC__)
+ static size_t sizes[] = {
+ 8, 32, 128, 4096, 32768, 131072, 1024000, 10240000, 20480000, 300000000
+ };
+
+ constexpr static size_t kMaxAllocs = 50;
+
+ for (size_t size : sizes) {
+ // If some of these allocations are stuck in a thread cache, then keep
+ // looping until we make an allocation that changes the total size of the
+ // memory allocated.
+ // jemalloc implementations counts the thread cache allocations against
+ // total memory allocated.
+ void* ptrs[kMaxAllocs] = {};
+ bool pass = false;
+ for (size_t i = 0; i < kMaxAllocs; i++) {
+ size_t allocated = mallinfo().uordblks;
+ ptrs[i] = malloc(size);
+ ASSERT_TRUE(ptrs[i] != nullptr);
+ size_t new_allocated = mallinfo().uordblks;
+ if (allocated != new_allocated) {
+ size_t usable_size = malloc_usable_size(ptrs[i]);
+ ASSERT_GE(new_allocated, allocated + usable_size)
+ << "Failed at size " << size << " usable size " << usable_size;
+ pass = true;
+ break;
+ }
+ }
+ for (void* ptr : ptrs) {
+ free(ptr);
+ }
+ ASSERT_TRUE(pass)
+ << "For size " << size << " allocated bytes did not increase after "
+ << kMaxAllocs << " allocations.";
+ }
+#else
+ GTEST_LOG_(INFO) << "Host glibc does not pass this test, skipping.\n";
+#endif
+}