Merge "Fix format macros for fast16 and fast32 int types."
diff --git a/libc/arch-arm/bionic/__bionic_clone.S b/libc/arch-arm/bionic/__bionic_clone.S
index 8836748..6669b93 100644
--- a/libc/arch-arm/bionic/__bionic_clone.S
+++ b/libc/arch-arm/bionic/__bionic_clone.S
@@ -29,7 +29,7 @@
#include <private/bionic_asm.h>
// pid_t __bionic_clone(int flags, void* child_stack, pid_t* parent_tid, void* tls, pid_t* child_tid, int (*fn)(void*), void* arg);
-ENTRY(__bionic_clone)
+ENTRY_PRIVATE(__bionic_clone)
mov ip, sp
# save registers to parent stack
stmfd sp!, {r4, r5, r6, r7}
@@ -67,4 +67,3 @@
pop {r0, r1}
b __start_thread
END(__bionic_clone)
-.hidden __bionic_clone
diff --git a/libc/arch-arm/cortex-a15/bionic/__strcat_chk.S b/libc/arch-arm/cortex-a15/bionic/__strcat_chk.S
index 3692f04..da40f6c 100644
--- a/libc/arch-arm/cortex-a15/bionic/__strcat_chk.S
+++ b/libc/arch-arm/cortex-a15/bionic/__strcat_chk.S
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2013 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,7 +26,174 @@
* SUCH DAMAGE.
*/
-// Indicate which memcpy base file to include.
-#define MEMCPY_BASE "memcpy_base.S"
+#include <private/bionic_asm.h>
-#include "__strcat_chk_common.S"
+ .syntax unified
+
+ .thumb
+ .thumb_func
+
+// Get the length of src string, then get the source of the dst string.
+// Check that the two lengths together don't exceed the threshold, then
+// do a memcpy of the data.
+ENTRY(__strcat_chk)
+ pld [r0, #0]
+ push {r0, lr}
+ .cfi_def_cfa_offset 8
+ .cfi_rel_offset r0, 0
+ .cfi_rel_offset lr, 4
+ push {r4, r5}
+ .cfi_adjust_cfa_offset 8
+ .cfi_rel_offset r4, 0
+ .cfi_rel_offset r5, 4
+
+ mov lr, r2
+
+ // Save the dst register to r5
+ mov r5, r0
+
+ // Zero out r4
+ eor r4, r4, r4
+
+ // r1 contains the address of the string to count.
+.L_strlen_start:
+ mov r0, r1
+ ands r3, r1, #7
+ beq .L_mainloop
+
+ // Align to a double word (64 bits).
+ rsb r3, r3, #8
+ lsls ip, r3, #31
+ beq .L_align_to_32
+
+ ldrb r2, [r1], #1
+ cbz r2, .L_update_count_and_finish
+
+.L_align_to_32:
+ bcc .L_align_to_64
+ ands ip, r3, #2
+ beq .L_align_to_64
+
+ ldrb r2, [r1], #1
+ cbz r2, .L_update_count_and_finish
+ ldrb r2, [r1], #1
+ cbz r2, .L_update_count_and_finish
+
+.L_align_to_64:
+ tst r3, #4
+ beq .L_mainloop
+ ldr r3, [r1], #4
+
+ sub ip, r3, #0x01010101
+ bic ip, ip, r3
+ ands ip, ip, #0x80808080
+ bne .L_zero_in_second_register
+
+ .p2align 2
+.L_mainloop:
+ ldrd r2, r3, [r1], #8
+
+ pld [r1, #64]
+
+ sub ip, r2, #0x01010101
+ bic ip, ip, r2
+ ands ip, ip, #0x80808080
+ bne .L_zero_in_first_register
+
+ sub ip, r3, #0x01010101
+ bic ip, ip, r3
+ ands ip, ip, #0x80808080
+ bne .L_zero_in_second_register
+ b .L_mainloop
+
+.L_update_count_and_finish:
+ sub r3, r1, r0
+ sub r3, r3, #1
+ b .L_finish
+
+.L_zero_in_first_register:
+ sub r3, r1, r0
+ lsls r2, ip, #17
+ bne .L_sub8_and_finish
+ bcs .L_sub7_and_finish
+ lsls ip, ip, #1
+ bne .L_sub6_and_finish
+
+ sub r3, r3, #5
+ b .L_finish
+
+.L_sub8_and_finish:
+ sub r3, r3, #8
+ b .L_finish
+
+.L_sub7_and_finish:
+ sub r3, r3, #7
+ b .L_finish
+
+.L_sub6_and_finish:
+ sub r3, r3, #6
+ b .L_finish
+
+.L_zero_in_second_register:
+ sub r3, r1, r0
+ lsls r2, ip, #17
+ bne .L_sub4_and_finish
+ bcs .L_sub3_and_finish
+ lsls ip, ip, #1
+ bne .L_sub2_and_finish
+
+ sub r3, r3, #1
+ b .L_finish
+
+.L_sub4_and_finish:
+ sub r3, r3, #4
+ b .L_finish
+
+.L_sub3_and_finish:
+ sub r3, r3, #3
+ b .L_finish
+
+.L_sub2_and_finish:
+ sub r3, r3, #2
+
+.L_finish:
+ cmp r4, #0
+ bne .L_strlen_done
+
+ // Time to get the dst string length.
+ mov r1, r5
+
+ // Save the original source address to r5.
+ mov r5, r0
+
+ // Save the current length (adding 1 for the terminator).
+ add r4, r3, #1
+ b .L_strlen_start
+
+ // r0 holds the pointer to the dst string.
+ // r3 holds the dst string length.
+ // r4 holds the src string length + 1.
+.L_strlen_done:
+ add r2, r3, r4
+ cmp r2, lr
+ itt hi
+ movhi r0, lr
+ bhi __strcat_chk_fail
+
+ // Set up the registers for the memcpy code.
+ mov r1, r5
+ pld [r1, #64]
+ mov r2, r4
+ add r0, r0, r3
+ pop {r4, r5}
+ .cfi_adjust_cfa_offset -8
+ .cfi_restore r4
+ .cfi_restore r5
+
+#include "memcpy_base.S"
+
+ // Undo the above cfi directives
+ .cfi_adjust_cfa_offset 8
+ .cfi_rel_offset r4, 0
+ .cfi_rel_offset r5, 4
+END(__strcat_chk)
diff --git a/libc/arch-arm/cortex-a15/bionic/__strcat_chk_common.S b/libc/arch-arm/cortex-a15/bionic/__strcat_chk_common.S
deleted file mode 100644
index a610dd5..0000000
--- a/libc/arch-arm/cortex-a15/bionic/__strcat_chk_common.S
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2013 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>
-
- .syntax unified
-
- .thumb
- .thumb_func
-
-// Get the length of src string, then get the source of the dst string.
-// Check that the two lengths together don't exceed the threshold, then
-// do a memcpy of the data.
-ENTRY(__strcat_chk)
- pld [r0, #0]
- push {r0, lr}
- .cfi_def_cfa_offset 8
- .cfi_rel_offset r0, 0
- .cfi_rel_offset lr, 4
- push {r4, r5}
- .cfi_adjust_cfa_offset 8
- .cfi_rel_offset r4, 0
- .cfi_rel_offset r5, 4
-
- mov lr, r2
-
- // Save the dst register to r5
- mov r5, r0
-
- // Zero out r4
- eor r4, r4, r4
-
- // r1 contains the address of the string to count.
-.L_strlen_start:
- mov r0, r1
- ands r3, r1, #7
- beq .L_mainloop
-
- // Align to a double word (64 bits).
- rsb r3, r3, #8
- lsls ip, r3, #31
- beq .L_align_to_32
-
- ldrb r2, [r1], #1
- cbz r2, .L_update_count_and_finish
-
-.L_align_to_32:
- bcc .L_align_to_64
- ands ip, r3, #2
- beq .L_align_to_64
-
- ldrb r2, [r1], #1
- cbz r2, .L_update_count_and_finish
- ldrb r2, [r1], #1
- cbz r2, .L_update_count_and_finish
-
-.L_align_to_64:
- tst r3, #4
- beq .L_mainloop
- ldr r3, [r1], #4
-
- sub ip, r3, #0x01010101
- bic ip, ip, r3
- ands ip, ip, #0x80808080
- bne .L_zero_in_second_register
-
- .p2align 2
-.L_mainloop:
- ldrd r2, r3, [r1], #8
-
- pld [r1, #64]
-
- sub ip, r2, #0x01010101
- bic ip, ip, r2
- ands ip, ip, #0x80808080
- bne .L_zero_in_first_register
-
- sub ip, r3, #0x01010101
- bic ip, ip, r3
- ands ip, ip, #0x80808080
- bne .L_zero_in_second_register
- b .L_mainloop
-
-.L_update_count_and_finish:
- sub r3, r1, r0
- sub r3, r3, #1
- b .L_finish
-
-.L_zero_in_first_register:
- sub r3, r1, r0
- lsls r2, ip, #17
- bne .L_sub8_and_finish
- bcs .L_sub7_and_finish
- lsls ip, ip, #1
- bne .L_sub6_and_finish
-
- sub r3, r3, #5
- b .L_finish
-
-.L_sub8_and_finish:
- sub r3, r3, #8
- b .L_finish
-
-.L_sub7_and_finish:
- sub r3, r3, #7
- b .L_finish
-
-.L_sub6_and_finish:
- sub r3, r3, #6
- b .L_finish
-
-.L_zero_in_second_register:
- sub r3, r1, r0
- lsls r2, ip, #17
- bne .L_sub4_and_finish
- bcs .L_sub3_and_finish
- lsls ip, ip, #1
- bne .L_sub2_and_finish
-
- sub r3, r3, #1
- b .L_finish
-
-.L_sub4_and_finish:
- sub r3, r3, #4
- b .L_finish
-
-.L_sub3_and_finish:
- sub r3, r3, #3
- b .L_finish
-
-.L_sub2_and_finish:
- sub r3, r3, #2
-
-.L_finish:
- cmp r4, #0
- bne .L_strlen_done
-
- // Time to get the dst string length.
- mov r1, r5
-
- // Save the original source address to r5.
- mov r5, r0
-
- // Save the current length (adding 1 for the terminator).
- add r4, r3, #1
- b .L_strlen_start
-
- // r0 holds the pointer to the dst string.
- // r3 holds the dst string length.
- // r4 holds the src string length + 1.
-.L_strlen_done:
- add r2, r3, r4
- cmp r2, lr
- itt hi
- movhi r0, lr
- bhi __strcat_chk_fail
-
- // Set up the registers for the memcpy code.
- mov r1, r5
- pld [r1, #64]
- mov r2, r4
- add r0, r0, r3
- pop {r4, r5}
- .cfi_adjust_cfa_offset -8
- .cfi_restore r4
- .cfi_restore r5
-
-#include MEMCPY_BASE
-
- // Undo the above cfi directives
- .cfi_adjust_cfa_offset 8
- .cfi_rel_offset r4, 0
- .cfi_rel_offset r5, 4
-END(__strcat_chk)
diff --git a/libc/arch-arm/cortex-a15/bionic/__strcpy_chk.S b/libc/arch-arm/cortex-a15/bionic/__strcpy_chk.S
index d8cb3d9..026adcc 100644
--- a/libc/arch-arm/cortex-a15/bionic/__strcpy_chk.S
+++ b/libc/arch-arm/cortex-a15/bionic/__strcpy_chk.S
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2013 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,7 +26,136 @@
* SUCH DAMAGE.
*/
-// Indicate which memcpy base file to include.
-#define MEMCPY_BASE "memcpy_base.S"
+#include <private/bionic_asm.h>
-#include "__strcpy_chk_common.S"
+ .syntax unified
+
+ .thumb
+ .thumb_func
+
+// Get the length of the source string first, then do a memcpy of the data
+// instead of a strcpy.
+ENTRY(__strcpy_chk)
+ pld [r0, #0]
+ push {r0, lr}
+ .cfi_def_cfa_offset 8
+ .cfi_rel_offset r0, 0
+ .cfi_rel_offset lr, 4
+
+ mov lr, r2
+ mov r0, r1
+
+ ands r3, r1, #7
+ beq .L_mainloop
+
+ // Align to a double word (64 bits).
+ rsb r3, r3, #8
+ lsls ip, r3, #31
+ beq .L_align_to_32
+
+ ldrb r2, [r0], #1
+ cbz r2, .L_update_count_and_finish
+
+.L_align_to_32:
+ bcc .L_align_to_64
+ ands ip, r3, #2
+ beq .L_align_to_64
+
+ ldrb r2, [r0], #1
+ cbz r2, .L_update_count_and_finish
+ ldrb r2, [r0], #1
+ cbz r2, .L_update_count_and_finish
+
+.L_align_to_64:
+ tst r3, #4
+ beq .L_mainloop
+ ldr r3, [r0], #4
+
+ sub ip, r3, #0x01010101
+ bic ip, ip, r3
+ ands ip, ip, #0x80808080
+ bne .L_zero_in_second_register
+
+ .p2align 2
+.L_mainloop:
+ ldrd r2, r3, [r0], #8
+
+ pld [r0, #64]
+
+ sub ip, r2, #0x01010101
+ bic ip, ip, r2
+ ands ip, ip, #0x80808080
+ bne .L_zero_in_first_register
+
+ sub ip, r3, #0x01010101
+ bic ip, ip, r3
+ ands ip, ip, #0x80808080
+ bne .L_zero_in_second_register
+ b .L_mainloop
+
+.L_update_count_and_finish:
+ sub r3, r0, r1
+ sub r3, r3, #1
+ b .L_check_size
+
+.L_zero_in_first_register:
+ sub r3, r0, r1
+ lsls r2, ip, #17
+ bne .L_sub8_and_finish
+ bcs .L_sub7_and_finish
+ lsls ip, ip, #1
+ bne .L_sub6_and_finish
+
+ sub r3, r3, #5
+ b .L_check_size
+
+.L_sub8_and_finish:
+ sub r3, r3, #8
+ b .L_check_size
+
+.L_sub7_and_finish:
+ sub r3, r3, #7
+ b .L_check_size
+
+.L_sub6_and_finish:
+ sub r3, r3, #6
+ b .L_check_size
+
+.L_zero_in_second_register:
+ sub r3, r0, r1
+ lsls r2, ip, #17
+ bne .L_sub4_and_finish
+ bcs .L_sub3_and_finish
+ lsls ip, ip, #1
+ bne .L_sub2_and_finish
+
+ sub r3, r3, #1
+ b .L_check_size
+
+.L_sub4_and_finish:
+ sub r3, r3, #4
+ b .L_check_size
+
+.L_sub3_and_finish:
+ sub r3, r3, #3
+ b .L_check_size
+
+.L_sub2_and_finish:
+ sub r3, r3, #2
+
+.L_check_size:
+ pld [r1, #0]
+ pld [r1, #64]
+ ldr r0, [sp]
+
+ // Add 1 for copy length to get the string terminator.
+ add r2, r3, #1
+
+ cmp r2, lr
+ itt hi
+ movhi r0, r2
+ bhi __strcpy_chk_fail
+
+#include "memcpy_base.S"
+
+END(__strcpy_chk)
diff --git a/libc/arch-arm/cortex-a15/bionic/__strcpy_chk_common.S b/libc/arch-arm/cortex-a15/bionic/__strcpy_chk_common.S
deleted file mode 100644
index 377e720..0000000
--- a/libc/arch-arm/cortex-a15/bionic/__strcpy_chk_common.S
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2013 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>
-
- .syntax unified
-
- .thumb
- .thumb_func
-
-// Get the length of the source string first, then do a memcpy of the data
-// instead of a strcpy.
-ENTRY(__strcpy_chk)
- pld [r0, #0]
- push {r0, lr}
- .cfi_def_cfa_offset 8
- .cfi_rel_offset r0, 0
- .cfi_rel_offset lr, 4
-
- mov lr, r2
- mov r0, r1
-
- ands r3, r1, #7
- beq .L_mainloop
-
- // Align to a double word (64 bits).
- rsb r3, r3, #8
- lsls ip, r3, #31
- beq .L_align_to_32
-
- ldrb r2, [r0], #1
- cbz r2, .L_update_count_and_finish
-
-.L_align_to_32:
- bcc .L_align_to_64
- ands ip, r3, #2
- beq .L_align_to_64
-
- ldrb r2, [r0], #1
- cbz r2, .L_update_count_and_finish
- ldrb r2, [r0], #1
- cbz r2, .L_update_count_and_finish
-
-.L_align_to_64:
- tst r3, #4
- beq .L_mainloop
- ldr r3, [r0], #4
-
- sub ip, r3, #0x01010101
- bic ip, ip, r3
- ands ip, ip, #0x80808080
- bne .L_zero_in_second_register
-
- .p2align 2
-.L_mainloop:
- ldrd r2, r3, [r0], #8
-
- pld [r0, #64]
-
- sub ip, r2, #0x01010101
- bic ip, ip, r2
- ands ip, ip, #0x80808080
- bne .L_zero_in_first_register
-
- sub ip, r3, #0x01010101
- bic ip, ip, r3
- ands ip, ip, #0x80808080
- bne .L_zero_in_second_register
- b .L_mainloop
-
-.L_update_count_and_finish:
- sub r3, r0, r1
- sub r3, r3, #1
- b .L_check_size
-
-.L_zero_in_first_register:
- sub r3, r0, r1
- lsls r2, ip, #17
- bne .L_sub8_and_finish
- bcs .L_sub7_and_finish
- lsls ip, ip, #1
- bne .L_sub6_and_finish
-
- sub r3, r3, #5
- b .L_check_size
-
-.L_sub8_and_finish:
- sub r3, r3, #8
- b .L_check_size
-
-.L_sub7_and_finish:
- sub r3, r3, #7
- b .L_check_size
-
-.L_sub6_and_finish:
- sub r3, r3, #6
- b .L_check_size
-
-.L_zero_in_second_register:
- sub r3, r0, r1
- lsls r2, ip, #17
- bne .L_sub4_and_finish
- bcs .L_sub3_and_finish
- lsls ip, ip, #1
- bne .L_sub2_and_finish
-
- sub r3, r3, #1
- b .L_check_size
-
-.L_sub4_and_finish:
- sub r3, r3, #4
- b .L_check_size
-
-.L_sub3_and_finish:
- sub r3, r3, #3
- b .L_check_size
-
-.L_sub2_and_finish:
- sub r3, r3, #2
-
-.L_check_size:
- pld [r1, #0]
- pld [r1, #64]
- ldr r0, [sp]
-
- // Add 1 for copy length to get the string terminator.
- add r2, r3, #1
-
- cmp r2, lr
- itt hi
- movhi r0, r2
- bhi __strcpy_chk_fail
-
-#include MEMCPY_BASE
-
-END(__strcpy_chk)
diff --git a/libc/arch-arm/cortex-a15/bionic/memcpy.S b/libc/arch-arm/cortex-a15/bionic/memcpy.S
index 537f3de..9407a08 100644
--- a/libc/arch-arm/cortex-a15/bionic/memcpy.S
+++ b/libc/arch-arm/cortex-a15/bionic/memcpy.S
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2008 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,8 +25,58 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
+/*
+ * Copyright (c) 2013 ARM Ltd
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the company may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ARM LTD ``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 ARM LTD 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.
+ */
-// Indicate which memcpy base file to include.
-#define MEMCPY_BASE "memcpy_base.S"
+#include <private/bionic_asm.h>
-#include "memcpy_common.S"
+ .text
+ .syntax unified
+ .fpu neon
+
+ENTRY(__memcpy_chk)
+ cmp r2, r3
+ bls memcpy
+
+ // Preserve lr for backtrace.
+ push {lr}
+ .cfi_def_cfa_offset 4
+ .cfi_rel_offset lr, 0
+ bl __memcpy_chk_fail
+END(__memcpy_chk)
+
+// Prototype: void *memcpy (void *dst, const void *src, size_t count).
+ENTRY(memcpy)
+ pld [r1, #64]
+ push {r0, lr}
+ .cfi_def_cfa_offset 8
+ .cfi_rel_offset r0, 0
+ .cfi_rel_offset lr, 4
+
+#include "memcpy_base.S"
+END(memcpy)
diff --git a/libc/arch-arm/cortex-a15/bionic/memcpy_base.S b/libc/arch-arm/cortex-a15/bionic/memcpy_base.S
index aac737d..1d152bb 100644
--- a/libc/arch-arm/cortex-a15/bionic/memcpy_base.S
+++ b/libc/arch-arm/cortex-a15/bionic/memcpy_base.S
@@ -68,11 +68,6 @@
cmp r2, #16
blo .L_copy_less_than_16_unknown_align
- // TODO: The aligned copy code is extremely slow copying some large
- // buffers so always go through the unaligned path for now.
- //cmp r2, #832
- //bge .L_check_alignment
-
.L_copy_unknown_alignment:
// Unknown alignment of src and dst.
// Assumes that the first few bytes have already been prefetched.
@@ -157,178 +152,3 @@
strbcs lr, [r0]
pop {r0, pc}
-
-.L_check_alignment:
- // If src and dst cannot both be aligned to a word boundary,
- // use the unaligned copy version.
- eor r3, r0, r1
- ands r3, r3, #0x3
- bne .L_copy_unknown_alignment
-
- // To try and improve performance, stack layout changed,
- // i.e., not keeping the stack looking like users expect
- // (highest numbered register at highest address).
- strd r4, r5, [sp, #-8]!
- .cfi_adjust_cfa_offset 8
- .cfi_rel_offset r4, 0
- .cfi_rel_offset r5, 4
- strd r6, r7, [sp, #-8]!
- .cfi_adjust_cfa_offset 8
- .cfi_rel_offset r6, 0
- .cfi_rel_offset r7, 4
- strd r8, r9, [sp, #-8]!
- .cfi_adjust_cfa_offset 8
- .cfi_rel_offset r8, 0
- .cfi_rel_offset r9, 4
-
- // Optimized for already aligned dst code.
- ands ip, r0, #3
- bne .L_dst_not_word_aligned
-
-.L_word_aligned:
- // Align the destination buffer to 8 bytes, to make sure double
- // loads and stores don't cross a cache line boundary,
- // as they are then more expensive even if the data is in the cache
- // (require two load/store issue cycles instead of one).
- // If only one of the buffers is not 8 bytes aligned,
- // then it's more important to align dst than src,
- // because there is more penalty for stores
- // than loads that cross a cacheline boundary.
- // This check and realignment are only done if there is >= 832
- // bytes to copy.
-
- // Dst is word aligned, but check if it is already double word aligned.
- ands r3, r0, #4
- beq 1f
- ldr r3, [r1], #4
- str r3, [r0], #4
- sub r2, #4
-
-1: // Can only get here if > 64 bytes to copy, so don't do check r2.
- sub r2, #64
-
-2: // Every loop iteration copies 64 bytes.
- .irp offset, #0, #8, #16, #24, #32
- ldrd r4, r5, [r1, \offset]
- strd r4, r5, [r0, \offset]
- .endr
-
- ldrd r4, r5, [r1, #40]
- ldrd r6, r7, [r1, #48]
- ldrd r8, r9, [r1, #56]
-
- // Keep the pld as far from the next load as possible.
- // The amount to prefetch was determined experimentally using
- // large sizes, and verifying the prefetch size does not affect
- // the smaller copies too much.
- // WARNING: If the ldrd and strd instructions get too far away
- // from each other, performance suffers. Three loads
- // in a row is the best tradeoff.
- pld [r1, #(64*16)]
- strd r4, r5, [r0, #40]
- strd r6, r7, [r0, #48]
- strd r8, r9, [r0, #56]
-
- add r0, r0, #64
- add r1, r1, #64
- subs r2, r2, #64
- bge 2b
-
- // Fix-up the remaining count and make sure we have >= 32 bytes left.
- adds r2, r2, #32
- blo 4f
-
- // Copy 32 bytes. These cache lines were already preloaded.
- .irp offset, #0, #8, #16, #24
- ldrd r4, r5, [r1, \offset]
- strd r4, r5, [r0, \offset]
- .endr
- add r1, r1, #32
- add r0, r0, #32
- sub r2, r2, #32
-4: // Less than 32 left.
- add r2, r2, #32
- tst r2, #0x10
- beq 5f
- // Copy 16 bytes.
- .irp offset, #0, #8
- ldrd r4, r5, [r1, \offset]
- strd r4, r5, [r0, \offset]
- .endr
- add r1, r1, #16
- add r0, r0, #16
-
-5: // Copy up to 15 bytes (count in r2).
- movs ip, r2, lsl #29
- bcc 1f
- // Copy 8 bytes.
- ldrd r4, r5, [r1], #8
- strd r4, r5, [r0], #8
-1: bge 2f
- // Copy 4 bytes.
- ldr r4, [r1], #4
- str r4, [r0], #4
-2: // Copy 0 to 4 bytes.
- lsls r2, r2, #31
- itt ne
- ldrbne lr, [r1], #1
- strbne lr, [r0], #1
- itttt cs
- ldrbcs ip, [r1], #1
- ldrbcs lr, [r1]
- strbcs ip, [r0], #1
- strbcs lr, [r0]
-
- // Restore registers: optimized pop {r0, pc}
- ldrd r8, r9, [sp], #8
- .cfi_adjust_cfa_offset -8
- .cfi_restore r8
- .cfi_restore r9
- ldrd r6, r7, [sp], #8
- .cfi_adjust_cfa_offset -8
- .cfi_restore r6
- .cfi_restore r7
- ldrd r4, r5, [sp], #8
- .cfi_adjust_cfa_offset -8
- .cfi_restore r4
- .cfi_restore r5
- pop {r0, pc}
-
- // Put the cfi directives back for the below instructions.
- .cfi_adjust_cfa_offset 24
- .cfi_rel_offset r4, 0
- .cfi_rel_offset r5, 4
- .cfi_rel_offset r6, 8
- .cfi_rel_offset r7, 12
- .cfi_rel_offset r8, 16
- .cfi_rel_offset r9, 20
-
-.L_dst_not_word_aligned:
- // Align dst to word.
- rsb ip, ip, #4
- cmp ip, #2
-
- itt gt
- ldrbgt lr, [r1], #1
- strbgt lr, [r0], #1
-
- itt ge
- ldrbge lr, [r1], #1
- strbge lr, [r0], #1
-
- ldrb lr, [r1], #1
- strb lr, [r0], #1
-
- sub r2, r2, ip
-
- // Src is guaranteed to be at least word aligned by this point.
- b .L_word_aligned
-
- // Undo any cfi directives from above.
- .cfi_adjust_cfa_offset -24
- .cfi_restore r4
- .cfi_restore r5
- .cfi_restore r6
- .cfi_restore r7
- .cfi_restore r8
- .cfi_restore r9
diff --git a/libc/arch-arm/cortex-a15/bionic/memcpy_common.S b/libc/arch-arm/cortex-a15/bionic/memcpy_common.S
deleted file mode 100644
index 4d1167f..0000000
--- a/libc/arch-arm/cortex-a15/bionic/memcpy_common.S
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2008 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.
- */
-/*
- * Copyright (c) 2013 ARM Ltd
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the company may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY ARM LTD ``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 ARM LTD 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>
-
- .text
- .syntax unified
- .fpu neon
-
-ENTRY(__memcpy_chk)
- cmp r2, r3
- bls memcpy
-
- // Preserve lr for backtrace.
- push {lr}
- .cfi_def_cfa_offset 4
- .cfi_rel_offset lr, 0
- bl __memcpy_chk_fail
-END(__memcpy_chk)
-
-// Prototype: void *memcpy (void *dst, const void *src, size_t count).
-ENTRY(memcpy)
- pld [r1, #64]
- push {r0, lr}
- .cfi_def_cfa_offset 8
- .cfi_rel_offset r0, 0
- .cfi_rel_offset lr, 4
-
-#include MEMCPY_BASE
-END(memcpy)
diff --git a/libc/arch-arm64/bionic/__bionic_clone.S b/libc/arch-arm64/bionic/__bionic_clone.S
index 27e44e7..c3ff0e5 100644
--- a/libc/arch-arm64/bionic/__bionic_clone.S
+++ b/libc/arch-arm64/bionic/__bionic_clone.S
@@ -30,7 +30,7 @@
// pid_t __bionic_clone(int flags, void* child_stack, pid_t* parent_tid, void* tls, pid_t* child_tid, int (*fn)(void*), void* arg);
-ENTRY(__bionic_clone)
+ENTRY_PRIVATE(__bionic_clone)
# Push 'fn' and 'arg' onto the child stack.
stp x5, x6, [x1, #-16]!
@@ -57,4 +57,3 @@
ldp x0, x1, [sp], #16
b __start_thread
END(__bionic_clone)
-.hidden __bionic_clone
diff --git a/libc/arch-mips/bionic/__bionic_clone.S b/libc/arch-mips/bionic/__bionic_clone.S
index b216efe..a3cacd1 100644
--- a/libc/arch-mips/bionic/__bionic_clone.S
+++ b/libc/arch-mips/bionic/__bionic_clone.S
@@ -31,7 +31,7 @@
#include <linux/sched.h>
// pid_t __bionic_clone(int flags, void* child_stack, pid_t* parent_tid, void* tls, pid_t* child_tid, int (*fn)(void*), void* arg);
-ENTRY(__bionic_clone)
+ENTRY_PRIVATE(__bionic_clone)
.set noreorder
.cpload t9
.set reorder
@@ -69,4 +69,3 @@
la t9,__set_errno_internal
j t9
END(__bionic_clone)
-.hidden __bionic_clone
diff --git a/libc/arch-mips/include/machine/asm.h b/libc/arch-mips/include/machine/asm.h
index 74412c1..dc83088 100644
--- a/libc/arch-mips/include/machine/asm.h
+++ b/libc/arch-mips/include/machine/asm.h
@@ -28,7 +28,7 @@
#ifndef _MIPS64_ASM_H
#define _MIPS64_ASM_H
-#define __bionic_asm_align 4
+#define __bionic_asm_align 16
#undef __bionic_asm_custom_entry
#undef __bionic_asm_custom_end
diff --git a/libc/arch-x86/bionic/__bionic_clone.S b/libc/arch-x86/bionic/__bionic_clone.S
index 1a6f642..b682b48 100644
--- a/libc/arch-x86/bionic/__bionic_clone.S
+++ b/libc/arch-x86/bionic/__bionic_clone.S
@@ -1,7 +1,7 @@
#include <private/bionic_asm.h>
// pid_t __bionic_clone(int flags, void* child_stack, pid_t* parent_tid, void* tls, pid_t* child_tid, int (*fn)(void*), void* arg);
-ENTRY(__bionic_clone)
+ENTRY_PRIVATE(__bionic_clone)
pushl %ebx
.cfi_adjust_cfa_offset 4
.cfi_rel_offset ebx, 0
@@ -62,4 +62,3 @@
.cfi_restore ebx
ret
END(__bionic_clone)
-.hidden __bionic_clone
diff --git a/libc/arch-x86_64/bionic/__bionic_clone.S b/libc/arch-x86_64/bionic/__bionic_clone.S
index 0c73e5f..a4245b8 100644
--- a/libc/arch-x86_64/bionic/__bionic_clone.S
+++ b/libc/arch-x86_64/bionic/__bionic_clone.S
@@ -29,7 +29,7 @@
#include <private/bionic_asm.h>
// pid_t __bionic_clone(int flags, void* child_stack, pid_t* parent_tid, void* tls, pid_t* child_tid, int (*fn)(void*), void* arg);
-ENTRY(__bionic_clone)
+ENTRY_PRIVATE(__bionic_clone)
# Copy 'fn' and 'arg' onto the child stack.
movq %r9, -16(%rsi) # fn
movq 8(%rsp), %rax # Read 'arg'.
@@ -74,4 +74,3 @@
# We're the parent; nothing to do.
ret
END(__bionic_clone)
-.hidden __bionic_clone
diff --git a/libc/bionic/clone.cpp b/libc/bionic/clone.cpp
index 8281ac8..3a20aa9 100644
--- a/libc/bionic/clone.cpp
+++ b/libc/bionic/clone.cpp
@@ -38,6 +38,11 @@
// Called from the __bionic_clone assembler to call the thread function then exit.
extern "C" __LIBC_HIDDEN__ void __start_thread(int (*fn)(void*), void* arg) {
+ pthread_internal_t* self = __get_thread();
+ if (self && self->tid == -1) {
+ self->tid = syscall(__NR_gettid);
+ }
+
int status = (*fn)(arg);
__exit(status);
}
@@ -75,6 +80,15 @@
pthread_internal_t* self = __get_thread();
pid_t parent_pid = self->invalidate_cached_pid();
+ // Remmber the caller's tid so that it can be restored in the parent after clone.
+ pid_t caller_tid = self->tid;
+ // Invalidate the tid before the syscall. The value is lazily cached in gettid(),
+ // and it will be updated by fork() and pthread_create(). We don't do this if
+ // we are sharing address space with the child.
+ if (!(flags & (CLONE_VM|CLONE_VFORK))) {
+ self->tid = -1;
+ }
+
// Actually do the clone.
int clone_result;
if (fn != nullptr) {
@@ -87,11 +101,19 @@
#endif
}
- // We're the parent, so put our known pid back in place.
- // We leave the child without a cached pid, but:
- // 1. pthread_create gives its children their own pthread_internal_t with the correct pid.
- // 2. fork makes a clone system call directly.
- // If any other cases become important, we could use a double trampoline like __pthread_start.
- self->set_cached_pid(parent_pid);
+ if (clone_result != 0) {
+ // We're the parent, so put our known pid and tid back in place.
+ // We leave the child without a cached pid and tid, but:
+ // 1. pthread_create gives its children their own pthread_internal_t with the correct pid and tid.
+ // 2. fork uses CLONE_CHILD_SETTID to get the new pid/tid.
+ // 3. The tid is lazily fetched in gettid().
+ // If any other cases become important, we could use a double trampoline like __pthread_start.
+ self->set_cached_pid(parent_pid);
+ self->tid = caller_tid;
+ } else if (self->tid == -1) {
+ self->tid = syscall(__NR_gettid);
+ self->set_cached_pid(self->tid);
+ }
+
return clone_result;
}
diff --git a/libc/bionic/fork.cpp b/libc/bionic/fork.cpp
index ffe94f4..32ea255 100644
--- a/libc/bionic/fork.cpp
+++ b/libc/bionic/fork.cpp
@@ -36,9 +36,6 @@
pthread_internal_t* self = __get_thread();
- // Remember the parent pid and invalidate the cached value while we fork.
- pid_t parent_pid = self->invalidate_cached_pid();
-
int result = clone(nullptr,
nullptr,
(CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD),
@@ -47,10 +44,11 @@
nullptr,
&(self->tid));
if (result == 0) {
+ // Update the cached pid, since clone() will not set it directly (as
+ // self->tid is updated by the kernel).
self->set_cached_pid(gettid());
__bionic_atfork_run_child();
} else {
- self->set_cached_pid(parent_pid);
__bionic_atfork_run_parent();
}
return result;
diff --git a/libc/bionic/gettid.cpp b/libc/bionic/gettid.cpp
index f42e36a..fe25a4d 100644
--- a/libc/bionic/gettid.cpp
+++ b/libc/bionic/gettid.cpp
@@ -31,5 +31,14 @@
#include "pthread_internal.h"
pid_t gettid() {
- return __get_thread()->tid;
+ pthread_internal_t* self = __get_thread();
+ if (__predict_true(self)) {
+ pid_t tid = self->tid;
+ if (__predict_true(tid != -1)) {
+ return tid;
+ }
+ self->tid = syscall(__NR_gettid);
+ return self->tid;
+ }
+ return syscall(__NR_gettid);
}
diff --git a/libc/include/android/legacy_ctype_inlines.h b/libc/include/android/legacy_ctype_inlines.h
deleted file mode 100644
index ca01e3f..0000000
--- a/libc/include/android/legacy_ctype_inlines.h
+++ /dev/null
@@ -1,87 +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 ANDROID_LEGACY_CTYPE_INLINES_H
-#define ANDROID_LEGACY_CTYPE_INLINES_H
-
-#include <ctype.h>
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-
-#if __ANDROID_API__ < 21
-
-static __inline int isalnum_l(int c, locale_t l __unused) {
- return isalnum(c);
-}
-
-static __inline int isalpha_l(int c, locale_t l __unused) {
- return isalpha(c);
-}
-
-static __inline int isblank_l(int c, locale_t l __unused) {
- return isblank(c);
-}
-
-static __inline int iscntrl_l(int c, locale_t l __unused) {
- return iscntrl(c);
-}
-
-static __inline int isdigit_l(int c, locale_t l __unused) {
- return isdigit(c);
-}
-
-static __inline int isgraph_l(int c, locale_t l __unused) {
- return isgraph(c);
-}
-
-static __inline int islower_l(int c, locale_t l __unused) {
- return islower(c);
-}
-
-static __inline int isprint_l(int c, locale_t l __unused) {
- return isprint(c);
-}
-
-static __inline int ispunct_l(int c, locale_t l __unused) {
- return ispunct(c);
-}
-
-static __inline int isspace_l(int c, locale_t l __unused) {
- return isspace(c);
-}
-
-static __inline int isupper_l(int c, locale_t l __unused) {
- return isupper(c);
-}
-
-static __inline int isxdigit_l(int c, locale_t l __unused) {
- return isxdigit(c);
-}
-
-static __inline int tolower_l(int c, locale_t l __unused) {
- return tolower(c);
-}
-
-static __inline int toupper_l(int c, locale_t l __unused) {
- return toupper(c);
-}
-
-#endif /* __ANDROID_API__ < 21 */
-
-__END_DECLS
-
-#endif /* ANDROID_LEGACY_CTYPE_INLINES_H */
diff --git a/libc/include/android/legacy_stdlib_inlines.h b/libc/include/android/legacy_stdlib_inlines.h
index 77fdd5d..93554e5 100644
--- a/libc/include/android/legacy_stdlib_inlines.h
+++ b/libc/include/android/legacy_stdlib_inlines.h
@@ -32,10 +32,10 @@
#include <stdlib.h>
#include <sys/cdefs.h>
-__BEGIN_DECLS
-
#if __ANDROID_API__ < 21
+__BEGIN_DECLS
+
static __inline float strtof(const char *nptr, char **endptr) {
return (float)strtod(nptr, endptr);
}
@@ -62,32 +62,7 @@
return 0; /* devpts does this all for us! */
}
-static __inline long double strtold_l(const char* nptr, char** endptr, locale_t l __unused) {
- return strtold(nptr, endptr);
-}
-
-static __inline long long strtoll_l(const char* nptr, char** endptr, int base, locale_t l __unused) {
- return strtoll(nptr, endptr, base);
-}
-
-static __inline unsigned long long strtoull_l(const char* nptr, char** endptr, int base,
- locale_t l __unused) {
- return strtoull(nptr, endptr, base);
-}
-
-#endif /* __ANDROID_API__ < 21 */
-
-#if __ANDROID_API__ < __ANDROID_API_FUTURE__
-
-static __inline float strtof_l(const char* nptr, char** endptr, locale_t l __unused) {
- return strtof(nptr, endptr);
-}
-
-static __inline double strtod_l(const char* nptr, char** endptr, locale_t l __unused) {
- return strtod(nptr, endptr);
-}
-
-#endif /* __ANDROID_API__ < __ANDROID_API_FUTURE__ */
-
__END_DECLS
+
+#endif
#endif /* _ANDROID_LEGACY_STDLIB_INLINES_H_ */
diff --git a/libc/include/android/legacy_string_inlines.h b/libc/include/android/legacy_string_inlines.h
deleted file mode 100644
index ceab909..0000000
--- a/libc/include/android/legacy_string_inlines.h
+++ /dev/null
@@ -1,41 +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 ANDROID_LEGACY_STRING_INLINES_H
-#define ANDROID_LEGACY_STRING_INLINES_H
-
-#include <string.h>
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-
-#if __ANDROID_API__ < 21
-
-static __inline __attribute_pure__ int strcoll_l(const char* _Nonnull s1, const char* _Nonnull s2,
- locale_t l __unused) {
- return strcoll(s1, s2);
-}
-
-size_t strxfrm_l(char* __restrict dest, const char* _Nonnull __restrict src, size_t n,
- locale_t l __unused) {
- return strxfrm(dest, src, n);
-}
-
-#endif /* __ANDROID_API__ < 21 */
-
-__END_DECLS
-
-#endif /* ANDROID_LEGACY_STRING_INLINES_H */
diff --git a/libc/include/android/legacy_sys_wait_inlines.h b/libc/include/android/legacy_sys_wait_inlines.h
new file mode 100644
index 0000000..63343eb
--- /dev/null
+++ b/libc/include/android/legacy_sys_wait_inlines.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef _ANDROID_LEGACY_SYS_WAIT_INLINES_H_
+#define _ANDROID_LEGACY_SYS_WAIT_INLINES_H_
+
+#include <sys/cdefs.h>
+#include <sys/syscall.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#if __ANDROID_API__ < 18
+
+__BEGIN_DECLS
+
+static __inline pid_t wait4(pid_t pid, int* status, int options, struct rusage* rusage) {
+ return __BIONIC_CAST(static_cast, pid_t, syscall(__NR_wait4, pid, status, options, rusage));
+}
+
+__END_DECLS
+
+#endif /* __ANDROID_API__ < 18 */
+
+#endif /* _ANDROID_LEGACY_SYS_WAIT_INLINES_H_ */
diff --git a/libc/include/android/legacy_time_inlines.h b/libc/include/android/legacy_time_inlines.h
deleted file mode 100644
index 319cc7c..0000000
--- a/libc/include/android/legacy_time_inlines.h
+++ /dev/null
@@ -1,36 +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 ANDROID_LEGACY_TIME_INLINES_H
-#define ANDROID_LEGACY_TIME_INLINES_H
-
-#include <sys/cdefs.h>
-#include <time.h>
-
-__BEGIN_DECLS
-
-#if __ANDROID_API__ < 21
-
-static __inline int strftime_l(char* s, size_t max, const char* format, const struct tm* tm,
- locale_t l __unused) {
- return strftime(s, max, format, tm);
-}
-
-#endif /* __ANDROID_API__ < 21 */
-
-__END_DECLS
-
-#endif /* ANDROID_LEGACY_TIME_INLINES_H */
diff --git a/libc/include/android/legacy_wchar_inlines.h b/libc/include/android/legacy_wchar_inlines.h
deleted file mode 100644
index 6c0d29e..0000000
--- a/libc/include/android/legacy_wchar_inlines.h
+++ /dev/null
@@ -1,54 +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 ANDROID_LEGACY_WCHAR_INLINES_H
-#define ANDROID_LEGACY_WCHAR_INLINES_H
-
-#include <sys/cdefs.h>
-#include <wchar.h>
-
-__BEGIN_DECLS
-
-#if __ANDROID_API__ < 21
-
-static __inline int wcscoll_l(const wchar_t* _Nonnull ws1, const wchar_t* _Nonnull ws2,
- locale_t l __unused) {
- return wcscoll(ws1, ws2);
-}
-
-size_t wcsxfrm_l(wchar_t* dest, const wchar_t* _Nonnull src, size_t n, locale_t l __unused) {
- return wcsxfrm(dest, src, n);
-}
-
-static inline long double wcstold_l(const wchar_t* nptr, wchar_t** endptr, locale_t l __unused) {
- return wcstold(nptr, endptr);
-}
-
-static inline long long wcstoll_l(const wchar_t* nptr, wchar_t** endptr, int base,
- locale_t l __unused) {
- return wcstoll(nptr, endptr, base);
-}
-
-static inline unsigned long long wcstoull_l(const wchar_t* nptr, wchar_t** endptr, int base,
- locale_t l __unused) {
- return wcstoull(nptr, endptr, base);
-}
-
-#endif /* __ANDROID_API__ < 21 */
-
-__END_DECLS
-
-#endif /* ANDROID_LEGACY_WCHAR_INLINES_H */
diff --git a/libc/include/android/legacy_wctype_inlines.h b/libc/include/android/legacy_wctype_inlines.h
deleted file mode 100644
index c490944..0000000
--- a/libc/include/android/legacy_wctype_inlines.h
+++ /dev/null
@@ -1,87 +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 ANDROID_LEGACY_WCTYPE_INLINES_H
-#define ANDROID_LEGACY_WCTYPE_INLINES_H
-
-#include <sys/cdefs.h>
-#include <wctype.h>
-
-__BEGIN_DECLS
-
-#if __ANDROID_API__ < 21
-
-static __inline int iswalnum_l(wint_t wc, locale_t l __unused) {
- return iswalnum(wc);
-}
-
-static __inline int iswalpha_l(wint_t wc, locale_t l __unused) {
- return iswalpha(wc);
-}
-
-static __inline int iswblank_l(wint_t wc, locale_t l __unused) {
- return iswblank(wc);
-}
-
-static __inline int iswcntrl_l(wint_t wc, locale_t l __unused) {
- return iswcntrl(wc);
-}
-
-static __inline int iswdigit_l(wint_t wc, locale_t l __unused) {
- return iswdigit(wc);
-}
-
-static __inline int iswgraph_l(wint_t wc, locale_t l __unused) {
- return iswgraph(wc);
-}
-
-static __inline int iswlower_l(wint_t wc, locale_t l __unused) {
- return iswlower(wc);
-}
-
-static __inline int iswprint_l(wint_t wc, locale_t l __unused) {
- return iswprint(wc);
-}
-
-static __inline int iswpunct_l(wint_t wc, locale_t l __unused) {
- return iswpunct(wc);
-}
-
-static __inline int iswspace_l(wint_t wc, locale_t l __unused) {
- return iswspace(wc);
-}
-
-static __inline int iswupper_l(wint_t wc, locale_t l __unused) {
- return iswupper(wc);
-}
-
-static __inline int iswxdigit_l(wint_t wc, locale_t l __unused) {
- return iswxdigit(wc);
-}
-
-static __inline wint_t towlower_l(wint_t wc, locale_t l __unused) {
- return towlower(wc);
-}
-
-static __inline wint_t towupper_l(wint_t wc, locale_t l __unused) {
- return towupper(wc);
-}
-
-#endif /* __ANDROID_API__ < 21 */
-
-__END_DECLS
-
-#endif /* ANDROID_LEGACY_WCTYPE_INLINES_H */
diff --git a/libc/include/ctype.h b/libc/include/ctype.h
index e1b237a..f59b399 100644
--- a/libc/include/ctype.h
+++ b/libc/include/ctype.h
@@ -102,6 +102,4 @@
__END_DECLS
-#include <android/legacy_ctype_inlines.h>
-
#endif /* !_CTYPE_H_ */
diff --git a/libc/include/string.h b/libc/include/string.h
index 0114e6a..b3b3ed0 100644
--- a/libc/include/string.h
+++ b/libc/include/string.h
@@ -391,6 +391,4 @@
__END_DECLS
-#include <android/legacy_string_inlines.h>
-
#endif /* _STRING_H */
diff --git a/libc/include/sys/wait.h b/libc/include/sys/wait.h
index 90eb35b..f3972fc 100644
--- a/libc/include/sys/wait.h
+++ b/libc/include/sys/wait.h
@@ -51,7 +51,11 @@
pid_t wait(int*);
pid_t waitpid(pid_t, int*, int);
+#if __ANDROID_API__ >= 18
pid_t wait4(pid_t, int*, int, struct rusage*) __INTRODUCED_IN(18);
+#else
+// Implemented as a static inline before 18.
+#endif
/* Posix states that idtype_t should be an enumeration type, but
* the kernel headers define P_ALL, P_PID and P_PGID as constant macros
@@ -63,4 +67,6 @@
__END_DECLS
+#include <android/legacy_sys_wait_inlines.h>
+
#endif /* _SYS_WAIT_H_ */
diff --git a/libc/include/time.h b/libc/include/time.h
index 898b816..37246b4 100644
--- a/libc/include/time.h
+++ b/libc/include/time.h
@@ -109,6 +109,4 @@
__END_DECLS
-#include <android/legacy_time_inlines.h>
-
#endif /* _TIME_H_ */
diff --git a/libc/include/wchar.h b/libc/include/wchar.h
index c3ad91c..2ee6c69 100644
--- a/libc/include/wchar.h
+++ b/libc/include/wchar.h
@@ -153,6 +153,4 @@
__END_DECLS
-#include <android/legacy_wchar_inlines.h>
-
#endif /* _WCHAR_H_ */
diff --git a/libc/include/wctype.h b/libc/include/wctype.h
index a77b212..0613e7e 100644
--- a/libc/include/wctype.h
+++ b/libc/include/wctype.h
@@ -63,6 +63,4 @@
__END_DECLS
-#include <android/legacy_wctype_inlines.h>
-
#endif /* _WCTYPE_H_ */
diff --git a/libc/private/bionic_asm.h b/libc/private/bionic_asm.h
index e2084d4..c1fab1f 100644
--- a/libc/private/bionic_asm.h
+++ b/libc/private/bionic_asm.h
@@ -41,7 +41,7 @@
#define ENTRY_NO_DWARF(f) \
.text; \
.globl f; \
- .align __bionic_asm_align; \
+ .balign __bionic_asm_align; \
.type f, __bionic_asm_function_type; \
f: \
__bionic_asm_custom_entry(f); \
diff --git a/libc/zoneinfo/tzdata b/libc/zoneinfo/tzdata
index abfe234..ce00600 100644
--- a/libc/zoneinfo/tzdata
+++ b/libc/zoneinfo/tzdata
Binary files differ
diff --git a/linker/arch/mips/begin.S b/linker/arch/mips/begin.S
index cbe1e37..1bdd358 100644
--- a/linker/arch/mips/begin.S
+++ b/linker/arch/mips/begin.S
@@ -27,7 +27,7 @@
*/
.text
- .align 4
+ .balign 16
.type __start,@function
.ent __start
diff --git a/linker/arch/mips64/begin.S b/linker/arch/mips64/begin.S
index 8f6b94a..b9637e7 100644
--- a/linker/arch/mips64/begin.S
+++ b/linker/arch/mips64/begin.S
@@ -41,7 +41,7 @@
#endif
.text
- .align 4
+ .balign 16
.type __start,@function
.ent __start
diff --git a/tests/sys_prctl_test.cpp b/tests/sys_prctl_test.cpp
index f1b08c1..8fdd28f 100644
--- a/tests/sys_prctl_test.cpp
+++ b/tests/sys_prctl_test.cpp
@@ -14,11 +14,19 @@
* limitations under the License.
*/
-#include <gtest/gtest.h>
-
+#include <inttypes.h>
+#include <stdio.h>
#include <sys/mman.h>
#include <sys/prctl.h>
#include <unistd.h>
+
+#include <string>
+#include <vector>
+
+#include <gtest/gtest.h>
+
+#include "android-base/file.h"
+#include "android-base/strings.h"
#include "private/bionic_prctl.h"
// http://b/20017123.
@@ -29,9 +37,27 @@
ASSERT_NE(MAP_FAILED, p);
ASSERT_EQ(0, mprotect(p, page_size, PROT_NONE));
ASSERT_NE(-1, prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, p, page_size * 3, "anonymous map space"));
- volatile char* vp = reinterpret_cast<volatile char*>(p);
- // Below memory access causes SEGV if the memory map is screwed up.
- *(vp + page_size) = 0;
+ // Now read the maps and verify that there are no overlapped maps.
+ std::string file_data;
+ ASSERT_TRUE(android::base::ReadFileToString("/proc/self/maps", &file_data));
+
+ uintptr_t last_start = 0;
+ uintptr_t last_end = 0;
+ std::vector<std::string> lines = android::base::Split(file_data, "\n");
+ for (size_t i = 0; i < lines.size(); i++) {
+ if (lines[i].empty()) {
+ continue;
+ }
+ uintptr_t start;
+ uintptr_t end;
+ ASSERT_EQ(2, sscanf(lines[i].c_str(), "%" SCNxPTR "-%" SCNxPTR " ", &start, &end))
+ << "Failed to parse line: " << lines[i];
+ // This will never fail on the first line, so no need to do any special checking.
+ ASSERT_GE(start, last_end) << "Overlapping map detected:\n" << lines[i -1] << lines[i];
+ last_start = start;
+ last_end = end;
+ }
+
ASSERT_EQ(0, munmap(p, page_size * 3));
#else
GTEST_LOG_(INFO) << "This test does nothing as it tests an Android specific kernel feature.";
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index 80ebf6b..b488e82 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -426,7 +426,7 @@
}
}
-static void TestGetPidCachingWithFork(int (*fork_fn)()) {
+static void TestGetPidCachingWithFork(int (*fork_fn)(), void (*exit_fn)(int)) {
pid_t parent_pid = getpid();
ASSERT_EQ(syscall(__NR_getpid), parent_pid);
@@ -434,9 +434,9 @@
ASSERT_NE(fork_result, -1);
if (fork_result == 0) {
// We're the child.
- AssertGetPidCorrect();
+ ASSERT_NO_FATAL_FAILURE(AssertGetPidCorrect());
ASSERT_EQ(parent_pid, getppid());
- _exit(123);
+ exit_fn(123);
} else {
// We're the parent.
ASSERT_EQ(parent_pid, getpid());
@@ -444,12 +444,98 @@
}
}
+// gettid() is marked as __attribute_const__, which will have the compiler
+// optimize out multiple calls to gettid in the same function. This wrapper
+// defeats that optimization.
+static __attribute__((__noinline__)) pid_t GetTidForTest() {
+ __asm__("");
+ return gettid();
+}
+
+static void AssertGetTidCorrect() {
+ // The loop is just to make manual testing/debugging with strace easier.
+ pid_t gettid_syscall_result = syscall(__NR_gettid);
+ for (size_t i = 0; i < 128; ++i) {
+ ASSERT_EQ(gettid_syscall_result, GetTidForTest());
+ }
+}
+
+static void TestGetTidCachingWithFork(int (*fork_fn)(), void (*exit_fn)(int)) {
+ pid_t parent_tid = GetTidForTest();
+ ASSERT_EQ(syscall(__NR_gettid), parent_tid);
+
+ pid_t fork_result = fork_fn();
+ ASSERT_NE(fork_result, -1);
+ if (fork_result == 0) {
+ // We're the child.
+ EXPECT_EQ(syscall(__NR_getpid), syscall(__NR_gettid));
+ EXPECT_EQ(getpid(), GetTidForTest()) << "real tid is " << syscall(__NR_gettid)
+ << ", pid is " << syscall(__NR_getpid);
+ ASSERT_NO_FATAL_FAILURE(AssertGetTidCorrect());
+ exit_fn(123);
+ } else {
+ // We're the parent.
+ ASSERT_EQ(parent_tid, GetTidForTest());
+ AssertChildExited(fork_result, 123);
+ }
+}
+
TEST(UNISTD_TEST, getpid_caching_and_fork) {
- TestGetPidCachingWithFork(fork);
+ TestGetPidCachingWithFork(fork, exit);
+}
+
+TEST(UNISTD_TEST, gettid_caching_and_fork) {
+ TestGetTidCachingWithFork(fork, exit);
}
TEST(UNISTD_TEST, getpid_caching_and_vfork) {
- TestGetPidCachingWithFork(vfork);
+ TestGetPidCachingWithFork(vfork, _exit);
+}
+
+static int CloneLikeFork() {
+ return clone(nullptr, nullptr, SIGCHLD, nullptr);
+}
+
+TEST(UNISTD_TEST, getpid_caching_and_clone_process) {
+ TestGetPidCachingWithFork(CloneLikeFork, exit);
+}
+
+TEST(UNISTD_TEST, gettid_caching_and_clone_process) {
+ TestGetTidCachingWithFork(CloneLikeFork, exit);
+}
+
+static int CloneAndSetTid() {
+ pid_t child_tid = 0;
+ pid_t parent_tid = GetTidForTest();
+
+ int rv = clone(nullptr, nullptr, CLONE_CHILD_SETTID | SIGCHLD, nullptr, nullptr, nullptr, &child_tid);
+ EXPECT_NE(-1, rv);
+
+ if (rv == 0) {
+ // Child.
+ EXPECT_EQ(child_tid, GetTidForTest());
+ EXPECT_NE(child_tid, parent_tid);
+ } else {
+ EXPECT_NE(child_tid, GetTidForTest());
+ EXPECT_NE(child_tid, parent_tid);
+ EXPECT_EQ(GetTidForTest(), parent_tid);
+ }
+
+ return rv;
+}
+
+TEST(UNISTD_TEST, gettid_caching_and_clone_process_settid) {
+ TestGetTidCachingWithFork(CloneAndSetTid, exit);
+}
+
+static int CloneStartRoutine(int (*start_routine)(void*)) {
+ void* child_stack[1024];
+ int clone_result = clone(start_routine, &child_stack[1024], CLONE_NEWNS | SIGCHLD, NULL);
+ if (clone_result == -1 && errno == EPERM && getuid() != 0) {
+ GTEST_LOG_(INFO) << "This test only works if you have permission to CLONE_NEWNS; try running as root.\n";
+ return clone_result;
+ }
+ return clone_result;
}
static int GetPidCachingCloneStartRoutine(void*) {
@@ -461,12 +547,7 @@
pid_t parent_pid = getpid();
ASSERT_EQ(syscall(__NR_getpid), parent_pid);
- void* child_stack[1024];
- int clone_result = clone(GetPidCachingCloneStartRoutine, &child_stack[1024], CLONE_NEWNS | SIGCHLD, NULL);
- if (clone_result == -1 && errno == EPERM && getuid() != 0) {
- GTEST_LOG_(INFO) << "This test only works if you have permission to CLONE_NEWNS; try running as root.\n";
- return;
- }
+ int clone_result = CloneStartRoutine(GetPidCachingCloneStartRoutine);
ASSERT_NE(clone_result, -1);
ASSERT_EQ(parent_pid, getpid());
@@ -474,6 +555,39 @@
AssertChildExited(clone_result, 123);
}
+static int GetTidCachingCloneStartRoutine(void*) {
+ AssertGetTidCorrect();
+ return 123;
+}
+
+TEST(UNISTD_TEST, gettid_caching_and_clone) {
+ pid_t parent_tid = GetTidForTest();
+ ASSERT_EQ(syscall(__NR_gettid), parent_tid);
+
+ int clone_result = CloneStartRoutine(GetTidCachingCloneStartRoutine);
+ ASSERT_NE(clone_result, -1);
+
+ ASSERT_EQ(parent_tid, GetTidForTest());
+
+ AssertChildExited(clone_result, 123);
+}
+
+static int CloneChildExit(void*) {
+ AssertGetPidCorrect();
+ AssertGetTidCorrect();
+ exit(33);
+}
+
+TEST(UNISTD_TEST, clone_fn_and_exit) {
+ int clone_result = CloneStartRoutine(CloneChildExit);
+ ASSERT_NE(-1, clone_result);
+
+ AssertGetPidCorrect();
+ AssertGetTidCorrect();
+
+ AssertChildExited(clone_result, 33);
+}
+
static void* GetPidCachingPthreadStartRoutine(void*) {
AssertGetPidCorrect();
return NULL;
@@ -492,6 +606,25 @@
ASSERT_EQ(NULL, result);
}
+static void* GetTidCachingPthreadStartRoutine(void*) {
+ AssertGetTidCorrect();
+ uint64_t tid = GetTidForTest();
+ return reinterpret_cast<void*>(tid);
+}
+
+TEST(UNISTD_TEST, gettid_caching_and_pthread_create) {
+ pid_t parent_tid = GetTidForTest();
+
+ pthread_t t;
+ ASSERT_EQ(0, pthread_create(&t, NULL, GetTidCachingPthreadStartRoutine, &parent_tid));
+
+ ASSERT_EQ(parent_tid, GetTidForTest());
+
+ void* result;
+ ASSERT_EQ(0, pthread_join(t, &result));
+ ASSERT_NE(static_cast<uint64_t>(parent_tid), reinterpret_cast<uint64_t>(result));
+}
+
class UNISTD_DEATHTEST : public BionicDeathTest {};
TEST_F(UNISTD_DEATHTEST, abort) {
diff --git a/tools/update_headers.sh b/tools/update_headers.sh
index 345b657..0095d50 100755
--- a/tools/update_headers.sh
+++ b/tools/update_headers.sh
@@ -35,11 +35,19 @@
HEADERS_INSTALL=$PREBUILTS_DIR/headers
if [ -d "$HEADERS_INSTALL" ]; then
git -C $PREBUILTS_DIR rm -r --ignore-unmatch $HEADERS_INSTALL
- rm -r $HEADERS_INSTALL
+ if [ -d $HEADERS_INSTALL ]; then
+ rm -r $HEADERS_INSTALL
+ fi
fi
versioner -p versioner/platforms versioner/current versioner/dependencies \
-o $HEADERS_INSTALL
+if [ $? -ne 0 ]; then
+ >&2 echo "Header preprocessing failed"
+ exit 1
+fi
-git -C $PREBUILTS_DIR add $HEADERS_INSTALL
+cp ../libc/NOTICE $PREBUILTS_DIR
+
+git -C $PREBUILTS_DIR add $HEADERS_INSTALL $PREBUILTS_DIR/NOTICE
git -C $PREBUILTS_DIR commit -m "Update bionic headers to $VERSION."
diff --git a/tools/versioner/src/DeclarationDatabase.h b/tools/versioner/src/DeclarationDatabase.h
index e957019..cf3589b 100644
--- a/tools/versioner/src/DeclarationDatabase.h
+++ b/tools/versioner/src/DeclarationDatabase.h
@@ -173,9 +173,9 @@
fprintf(out, "\n%s ", indent_str.c_str());
if (!calculateAvailability(&avail)) {
- fprintf(out, "invalid availability");
+ fprintf(out, "invalid availability\n");
} else {
- fprintf(out, "%s", to_string(avail).c_str());
+ fprintf(out, "%s\n", to_string(avail).c_str());
}
}
}
@@ -209,7 +209,6 @@
for (auto& it : declarations) {
it.second.dump(base_path, out, 4);
- fprintf(out, "\n");
}
}
};
diff --git a/tools/versioner/src/versioner.cpp b/tools/versioner/src/versioner.cpp
index 74650d5..2f0656c 100644
--- a/tools/versioner/src/versioner.cpp
+++ b/tools/versioner/src/versioner.cpp
@@ -276,6 +276,21 @@
return result;
}
+static std::set<CompilationType> getCompilationTypes(const Declaration* decl) {
+ std::set<CompilationType> result;
+ for (const auto& it : decl->availability) {
+ result.insert(it.first);
+ }
+ return result;
+}
+
+template<typename T>
+static std::vector<T> Intersection(const std::set<T>& a, const std::set<T>& b) {
+ std::vector<T> intersection;
+ std::set_intersection(a.begin(), a.end(), b.begin(), b.end(), std::back_inserter(intersection));
+ return intersection;
+}
+
// Perform a sanity check on a symbol's declarations, enforcing the following invariants:
// 1. At most one inline definition of the function exists.
// 2. All of the availability declarations for a symbol are compatible.
@@ -287,18 +302,23 @@
static bool checkSymbol(const Symbol& symbol) {
std::string cwd = getWorkingDir() + "/";
- const Declaration* inline_definition = nullptr;
+ std::unordered_map<const Declaration*, std::set<CompilationType>> inline_definitions;
for (const auto& decl_it : symbol.declarations) {
const Declaration* decl = &decl_it.second;
if (decl->is_definition) {
- if (inline_definition) {
- fprintf(stderr, "versioner: multiple definitions of symbol %s\n", symbol.name.c_str());
- symbol.dump(cwd);
- inline_definition->dump(cwd);
- return false;
+ std::set<CompilationType> compilation_types = getCompilationTypes(decl);
+ for (const auto& inline_def_it : inline_definitions) {
+ auto intersection = Intersection(compilation_types, inline_def_it.second);
+ if (!intersection.empty()) {
+ fprintf(stderr, "versioner: conflicting inline definitions:\n");
+ fprintf(stderr, " declarations visible in: %s\n", Join(intersection, ", ").c_str());
+ decl->dump(cwd, stderr, 4);
+ inline_def_it.first->dump(cwd, stderr, 4);
+ return false;
+ }
}
- inline_definition = decl;
+ inline_definitions[decl] = std::move(compilation_types);
}
DeclarationAvailability availability;
diff --git a/tools/versioner/tests/multiple_definition/expected_fail b/tools/versioner/tests/multiple_definition/expected_fail
new file mode 100644
index 0000000..6c531bd
--- /dev/null
+++ b/tools/versioner/tests/multiple_definition/expected_fail
@@ -0,0 +1,7 @@
+versioner: conflicting inline definitions:
+ declarations visible in: arm-9 [fob = 32], arm-9 [fob = 64], arm-12 [fob = 32], arm-12 [fob = 64]
+ static definition @ headers/foo.h:1:1
+ no availability
+ static definition @ headers/bar.h:1:1
+ no availability
+versioner: sanity check failed
diff --git a/tools/versioner/tests/multiple_definition/headers/bar.h b/tools/versioner/tests/multiple_definition/headers/bar.h
new file mode 100644
index 0000000..a9d0197
--- /dev/null
+++ b/tools/versioner/tests/multiple_definition/headers/bar.h
@@ -0,0 +1,3 @@
+static int foo() {
+ return 0;
+}
diff --git a/tools/versioner/tests/multiple_definition/headers/foo.h b/tools/versioner/tests/multiple_definition/headers/foo.h
new file mode 100644
index 0000000..a9d0197
--- /dev/null
+++ b/tools/versioner/tests/multiple_definition/headers/foo.h
@@ -0,0 +1,3 @@
+static int foo() {
+ return 0;
+}
diff --git a/tools/versioner/tests/multiple_definition/platforms/android-9/arch-arm/symbols/libc.so.functions.txt b/tools/versioner/tests/multiple_definition/platforms/android-9/arch-arm/symbols/libc.so.functions.txt
new file mode 100644
index 0000000..257cc56
--- /dev/null
+++ b/tools/versioner/tests/multiple_definition/platforms/android-9/arch-arm/symbols/libc.so.functions.txt
@@ -0,0 +1 @@
+foo
diff --git a/tools/versioner/tests/multiple_definition/run.sh b/tools/versioner/tests/multiple_definition/run.sh
new file mode 100644
index 0000000..e4abbe7
--- /dev/null
+++ b/tools/versioner/tests/multiple_definition/run.sh
@@ -0,0 +1 @@
+versioner headers -p platforms -r arm -a 9 -a 12 -i
diff --git a/tools/versioner/tests/multiple_definition_ok/headers/bar.h b/tools/versioner/tests/multiple_definition_ok/headers/bar.h
new file mode 100644
index 0000000..c3c87bb
--- /dev/null
+++ b/tools/versioner/tests/multiple_definition_ok/headers/bar.h
@@ -0,0 +1,5 @@
+#if __ANDROID_API__ == 12
+static int foo() {
+ return 0;
+}
+#endif
diff --git a/tools/versioner/tests/multiple_definition_ok/headers/foo.h b/tools/versioner/tests/multiple_definition_ok/headers/foo.h
new file mode 100644
index 0000000..9da9b2a
--- /dev/null
+++ b/tools/versioner/tests/multiple_definition_ok/headers/foo.h
@@ -0,0 +1,5 @@
+#if __ANDROID_API__ == 9
+static int foo() {
+ return 0;
+}
+#endif
diff --git a/tools/versioner/tests/multiple_definition_ok/platforms/android-9/arch-arm/symbols/libc.so.functions.txt b/tools/versioner/tests/multiple_definition_ok/platforms/android-9/arch-arm/symbols/libc.so.functions.txt
new file mode 100644
index 0000000..257cc56
--- /dev/null
+++ b/tools/versioner/tests/multiple_definition_ok/platforms/android-9/arch-arm/symbols/libc.so.functions.txt
@@ -0,0 +1 @@
+foo
diff --git a/tools/versioner/tests/multiple_definition_ok/run.sh b/tools/versioner/tests/multiple_definition_ok/run.sh
new file mode 100644
index 0000000..e4abbe7
--- /dev/null
+++ b/tools/versioner/tests/multiple_definition_ok/run.sh
@@ -0,0 +1 @@
+versioner headers -p platforms -r arm -a 9 -a 12 -i