Merge changes I660ddce6,Ic58d0481,I5d45aa72
* changes:
Mark LIBC_DEPRECATED as platform-only.
Remove _ZTV9type_info from the version script.
Run genversion-scripts.py.
diff --git a/libc/arch-arm/cortex-a53/bionic/__strcat_chk.S b/libc/arch-arm/cortex-a53/bionic/__strcat_chk.S
index c5bc98a..da40f6c 100644
--- a/libc/arch-arm/cortex-a53/bionic/__strcat_chk.S
+++ b/libc/arch-arm/cortex-a53/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 "arch-arm/cortex-a53/bionic/memcpy_base.S"
+#include <private/bionic_asm.h>
-#include "arch-arm/cortex-a15/bionic/__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-a53/bionic/__strcpy_chk.S b/libc/arch-arm/cortex-a53/bionic/__strcpy_chk.S
index 1f8945d..026adcc 100644
--- a/libc/arch-arm/cortex-a53/bionic/__strcpy_chk.S
+++ b/libc/arch-arm/cortex-a53/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 "arch-arm/cortex-a53/bionic/memcpy_base.S"
+#include <private/bionic_asm.h>
-#include "arch-arm/cortex-a15/bionic/__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-a53/bionic/memcpy.S b/libc/arch-arm/cortex-a53/bionic/memcpy.S
index 664f574..9407a08 100644
--- a/libc/arch-arm/cortex-a53/bionic/memcpy.S
+++ b/libc/arch-arm/cortex-a53/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 "arch-arm/cortex-a53/bionic/memcpy_base.S"
+#include <private/bionic_asm.h>
-#include "arch-arm/cortex-a15/bionic/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/bionic/clone.cpp b/libc/bionic/clone.cpp
index b50a96d..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);
}
@@ -105,6 +110,9 @@
// 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/include/inttypes.h b/libc/include/inttypes.h
index 2c268e6..f74afa3 100644
--- a/libc/include/inttypes.h
+++ b/libc/include/inttypes.h
@@ -29,6 +29,7 @@
#define __PRI_64_prefix "ll"
#define __PRI_PTR_prefix
#endif
+#define __PRI_FAST_prefix __PRI_PTR_prefix
/*
* 7.8.1 Macros for format specifiers
@@ -58,8 +59,8 @@
#define PRIdLEAST64 __PRI_64_prefix"d" /* int_least64_t */
#define PRIdFAST8 "d" /* int_fast8_t */
-#define PRIdFAST16 "d" /* int_fast16_t */
-#define PRIdFAST32 "d" /* int_fast32_t */
+#define PRIdFAST16 __PRI_FAST_prefix"d" /* int_fast16_t */
+#define PRIdFAST32 __PRI_FAST_prefix"d" /* int_fast32_t */
#define PRIdFAST64 __PRI_64_prefix"d" /* int_fast64_t */
#define PRIdMAX "jd" /* intmax_t */
@@ -76,8 +77,8 @@
#define PRIiLEAST64 __PRI_64_prefix"i" /* int_least64_t */
#define PRIiFAST8 "i" /* int_fast8_t */
-#define PRIiFAST16 "i" /* int_fast16_t */
-#define PRIiFAST32 "i" /* int_fast32_t */
+#define PRIiFAST16 __PRI_FAST_prefix"i" /* int_fast16_t */
+#define PRIiFAST32 __PRI_FAST_prefix"i" /* int_fast32_t */
#define PRIiFAST64 __PRI_64_prefix"i" /* int_fast64_t */
#define PRIiMAX "ji" /* intmax_t */
@@ -95,8 +96,8 @@
#define PRIoLEAST64 __PRI_64_prefix"o" /* int_least64_t */
#define PRIoFAST8 "o" /* int_fast8_t */
-#define PRIoFAST16 "o" /* int_fast16_t */
-#define PRIoFAST32 "o" /* int_fast32_t */
+#define PRIoFAST16 __PRI_FAST_prefix"o" /* int_fast16_t */
+#define PRIoFAST32 __PRI_FAST_prefix"o" /* int_fast32_t */
#define PRIoFAST64 __PRI_64_prefix"o" /* int_fast64_t */
#define PRIoMAX "jo" /* intmax_t */
@@ -113,8 +114,8 @@
#define PRIuLEAST64 __PRI_64_prefix"u" /* uint_least64_t */
#define PRIuFAST8 "u" /* uint_fast8_t */
-#define PRIuFAST16 "u" /* uint_fast16_t */
-#define PRIuFAST32 "u" /* uint_fast32_t */
+#define PRIuFAST16 __PRI_FAST_prefix"u" /* uint_fast16_t */
+#define PRIuFAST32 __PRI_FAST_prefix"u" /* uint_fast32_t */
#define PRIuFAST64 __PRI_64_prefix"u" /* uint_fast64_t */
#define PRIuMAX "ju" /* uintmax_t */
@@ -131,8 +132,8 @@
#define PRIxLEAST64 __PRI_64_prefix"x" /* uint_least64_t */
#define PRIxFAST8 "x" /* uint_fast8_t */
-#define PRIxFAST16 "x" /* uint_fast16_t */
-#define PRIxFAST32 "x" /* uint_fast32_t */
+#define PRIxFAST16 __PRI_FAST_prefix"x" /* uint_fast16_t */
+#define PRIxFAST32 __PRI_FAST_prefix"x" /* uint_fast32_t */
#define PRIxFAST64 __PRI_64_prefix"x" /* uint_fast64_t */
#define PRIxMAX "jx" /* uintmax_t */
@@ -149,8 +150,8 @@
#define PRIXLEAST64 __PRI_64_prefix"X" /* uint_least64_t */
#define PRIXFAST8 "X" /* uint_fast8_t */
-#define PRIXFAST16 "X" /* uint_fast16_t */
-#define PRIXFAST32 "X" /* uint_fast32_t */
+#define PRIXFAST16 __PRI_FAST_prefix"X" /* uint_fast16_t */
+#define PRIXFAST32 __PRI_FAST_prefix"X" /* uint_fast32_t */
#define PRIXFAST64 __PRI_64_prefix"X" /* uint_fast64_t */
#define PRIXMAX "jX" /* uintmax_t */
@@ -168,8 +169,8 @@
#define SCNdLEAST64 __PRI_64_prefix"d" /* int_least64_t */
#define SCNdFAST8 "hhd" /* int_fast8_t */
-#define SCNdFAST16 "hd" /* int_fast16_t */
-#define SCNdFAST32 "d" /* int_fast32_t */
+#define SCNdFAST16 __PRI_FAST_prefix"d" /* int_fast16_t */
+#define SCNdFAST32 __PRI_FAST_prefix"d" /* int_fast32_t */
#define SCNdFAST64 __PRI_64_prefix"d" /* int_fast64_t */
#define SCNdMAX "jd" /* intmax_t */
@@ -186,8 +187,8 @@
#define SCNiLEAST64 __PRI_64_prefix"i" /* int_least64_t */
#define SCNiFAST8 "hhi" /* int_fast8_t */
-#define SCNiFAST16 "hi" /* int_fast16_t */
-#define SCNiFAST32 "i" /* int_fast32_t */
+#define SCNiFAST16 __PRI_FAST_prefix"i" /* int_fast16_t */
+#define SCNiFAST32 __PRI_FAST_prefix"i" /* int_fast32_t */
#define SCNiFAST64 __PRI_64_prefix"i" /* int_fast64_t */
#define SCNiMAX "ji" /* intmax_t */
@@ -205,8 +206,8 @@
#define SCNoLEAST64 __PRI_64_prefix"o" /* uint_least64_t */
#define SCNoFAST8 "hho" /* uint_fast8_t */
-#define SCNoFAST16 "ho" /* uint_fast16_t */
-#define SCNoFAST32 "o" /* uint_fast32_t */
+#define SCNoFAST16 __PRI_FAST_prefix"o" /* uint_fast16_t */
+#define SCNoFAST32 __PRI_FAST_prefix"o" /* uint_fast32_t */
#define SCNoFAST64 __PRI_64_prefix"o" /* uint_fast64_t */
#define SCNoMAX "jo" /* uintmax_t */
@@ -223,8 +224,8 @@
#define SCNuLEAST64 __PRI_64_prefix"u" /* uint_least64_t */
#define SCNuFAST8 "hhu" /* uint_fast8_t */
-#define SCNuFAST16 "hu" /* uint_fast16_t */
-#define SCNuFAST32 "u" /* uint_fast32_t */
+#define SCNuFAST16 __PRI_FAST_prefix"u" /* uint_fast16_t */
+#define SCNuFAST32 __PRI_FAST_prefix"u" /* uint_fast32_t */
#define SCNuFAST64 __PRI_64_prefix"u" /* uint_fast64_t */
#define SCNuMAX "ju" /* uintmax_t */
@@ -241,8 +242,8 @@
#define SCNxLEAST64 __PRI_64_prefix"x" /* uint_least64_t */
#define SCNxFAST8 "hhx" /* uint_fast8_t */
-#define SCNxFAST16 "hx" /* uint_fast16_t */
-#define SCNxFAST32 "x" /* uint_fast32_t */
+#define SCNxFAST16 __PRI_FAST_prefix"x" /* uint_fast16_t */
+#define SCNxFAST32 __PRI_FAST_prefix"x" /* uint_fast32_t */
#define SCNxFAST64 __PRI_64_prefix"x" /* uint_fast64_t */
#define SCNxMAX "jx" /* uintmax_t */
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/tests/inttypes_test.cpp b/tests/inttypes_test.cpp
index dbbb6d4..80580a4 100644
--- a/tests/inttypes_test.cpp
+++ b/tests/inttypes_test.cpp
@@ -20,24 +20,81 @@
#include <gtest/gtest.h>
#include <stdio.h>
-TEST(inttypes, misc) {
- char buf[512];
+#define PRINTF_TYPED(FMT_SUFFIX, TYPE_SUFFIX) \
+ do { \
+ char buf[512]; \
+ memset(buf, 0, sizeof(buf)); \
+ snprintf(buf, sizeof(buf), "%" PRId##FMT_SUFFIX, int##TYPE_SUFFIX(123)); \
+ EXPECT_STREQ("123", buf); \
+ memset(buf, 0, sizeof(buf)); \
+ snprintf(buf, sizeof(buf), "%" PRIi##FMT_SUFFIX, int##TYPE_SUFFIX(123)); \
+ EXPECT_STREQ("123", buf); \
+ memset(buf, 0, sizeof(buf)); \
+ snprintf(buf, sizeof(buf), "%" PRIo##FMT_SUFFIX, int##TYPE_SUFFIX(123)); \
+ EXPECT_STREQ("173", buf); \
+ memset(buf, 0, sizeof(buf)); \
+ snprintf(buf, sizeof(buf), "%" PRIu##FMT_SUFFIX, uint##TYPE_SUFFIX(123)); \
+ EXPECT_STREQ("123", buf); \
+ memset(buf, 0, sizeof(buf)); \
+ snprintf(buf, sizeof(buf), "%" PRIx##FMT_SUFFIX, uint##TYPE_SUFFIX(123)); \
+ EXPECT_STREQ("7b", buf); \
+ memset(buf, 0, sizeof(buf)); \
+ snprintf(buf, sizeof(buf), "%" PRIX##FMT_SUFFIX, uint##TYPE_SUFFIX(123)); \
+ EXPECT_STREQ("7B", buf); \
+ } while (false) \
- intptr_t i = 0;
- uintptr_t u = 0;
+#define PRINTF_SIZED(WIDTH) \
+ PRINTF_TYPED(WIDTH, WIDTH##_t); \
+ PRINTF_TYPED(FAST##WIDTH, _fast##WIDTH##_t); \
+ PRINTF_TYPED(LEAST##WIDTH, _least##WIDTH##_t) \
- snprintf(buf, sizeof(buf), "%08" PRIdPTR, i);
- snprintf(buf, sizeof(buf), "%08" PRIiPTR, i);
- snprintf(buf, sizeof(buf), "%08" PRIoPTR, i);
- snprintf(buf, sizeof(buf), "%08" PRIuPTR, u);
- snprintf(buf, sizeof(buf), "%08" PRIxPTR, u);
- snprintf(buf, sizeof(buf), "%08" PRIXPTR, u);
- sscanf(buf, "%08" SCNdPTR, &i);
- sscanf(buf, "%08" SCNiPTR, &i);
- sscanf(buf, "%08" SCNoPTR, &u);
- sscanf(buf, "%08" SCNuPTR, &u);
- sscanf(buf, "%08" SCNxPTR, &u);
+#define SCANF_TYPED(FMT_SUFFIX, TYPE_SUFFIX) \
+ do { \
+ int##TYPE_SUFFIX dst_int##TYPE_SUFFIX = 0; \
+ uint##TYPE_SUFFIX dst_uint##TYPE_SUFFIX = 0u; \
+ \
+ sscanf("123", "%" SCNd##FMT_SUFFIX, &dst_int##TYPE_SUFFIX); \
+ EXPECT_EQ(123, dst_int##TYPE_SUFFIX); \
+ dst_int##TYPE_SUFFIX = 0; \
+ sscanf("123", "%" SCNi##FMT_SUFFIX, &dst_int##TYPE_SUFFIX); \
+ EXPECT_EQ(123, dst_int##TYPE_SUFFIX); \
+ dst_int##TYPE_SUFFIX = 0; \
+ sscanf("173", "%" SCNo##FMT_SUFFIX, &dst_int##TYPE_SUFFIX); \
+ EXPECT_EQ(123, dst_int##TYPE_SUFFIX); \
+ dst_int##TYPE_SUFFIX = 0; \
+ sscanf("123", "%" SCNu##FMT_SUFFIX, &dst_uint##TYPE_SUFFIX); \
+ EXPECT_EQ(123u, dst_uint##TYPE_SUFFIX); \
+ dst_uint##TYPE_SUFFIX = 0; \
+ sscanf("7B", "%" SCNx##FMT_SUFFIX, &dst_uint##TYPE_SUFFIX); \
+ EXPECT_EQ(123u, dst_uint##TYPE_SUFFIX); \
+ dst_uint##TYPE_SUFFIX = 0; \
+ } while (false) \
+
+#define SCANF_SIZED(SIZE) \
+ SCANF_TYPED(SIZE, SIZE##_t); \
+ SCANF_TYPED(FAST##SIZE, _fast##SIZE##_t); \
+ SCANF_TYPED(LEAST##SIZE, _least##SIZE##_t) \
+
+
+TEST(inttypes, printf_macros) {
+ PRINTF_SIZED(8);
+ PRINTF_SIZED(16);
+ PRINTF_SIZED(32);
+ PRINTF_SIZED(64);
+
+ PRINTF_TYPED(MAX, max_t);
+ PRINTF_TYPED(PTR, ptr_t);
+}
+
+TEST(inttypes, scanf_macros) {
+ SCANF_SIZED(8);
+ SCANF_SIZED(16);
+ SCANF_SIZED(32);
+ SCANF_SIZED(64);
+
+ SCANF_TYPED(MAX, max_t);
+ SCANF_TYPED(PTR, ptr_t);
}
TEST(inttypes, wcstoimax) {
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 660679f..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);
@@ -436,7 +436,7 @@
// We're the child.
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());
@@ -460,7 +460,7 @@
}
}
-static void TestGetTidCachingWithFork(int (*fork_fn)()) {
+static void TestGetTidCachingWithFork(int (*fork_fn)(), void (*exit_fn)(int)) {
pid_t parent_tid = GetTidForTest();
ASSERT_EQ(syscall(__NR_gettid), parent_tid);
@@ -472,7 +472,7 @@
EXPECT_EQ(getpid(), GetTidForTest()) << "real tid is " << syscall(__NR_gettid)
<< ", pid is " << syscall(__NR_getpid);
ASSERT_NO_FATAL_FAILURE(AssertGetTidCorrect());
- _exit(123);
+ exit_fn(123);
} else {
// We're the parent.
ASSERT_EQ(parent_tid, GetTidForTest());
@@ -481,15 +481,15 @@
}
TEST(UNISTD_TEST, getpid_caching_and_fork) {
- TestGetPidCachingWithFork(fork);
+ TestGetPidCachingWithFork(fork, exit);
}
TEST(UNISTD_TEST, gettid_caching_and_fork) {
- TestGetTidCachingWithFork(fork);
+ TestGetTidCachingWithFork(fork, exit);
}
TEST(UNISTD_TEST, getpid_caching_and_vfork) {
- TestGetPidCachingWithFork(vfork);
+ TestGetPidCachingWithFork(vfork, _exit);
}
static int CloneLikeFork() {
@@ -497,11 +497,11 @@
}
TEST(UNISTD_TEST, getpid_caching_and_clone_process) {
- TestGetPidCachingWithFork(CloneLikeFork);
+ TestGetPidCachingWithFork(CloneLikeFork, exit);
}
TEST(UNISTD_TEST, gettid_caching_and_clone_process) {
- TestGetTidCachingWithFork(CloneLikeFork);
+ TestGetTidCachingWithFork(CloneLikeFork, exit);
}
static int CloneAndSetTid() {
@@ -525,7 +525,7 @@
}
TEST(UNISTD_TEST, gettid_caching_and_clone_process_settid) {
- TestGetTidCachingWithFork(CloneAndSetTid);
+ TestGetTidCachingWithFork(CloneAndSetTid, exit);
}
static int CloneStartRoutine(int (*start_routine)(void*)) {
@@ -572,6 +572,22 @@
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;
diff --git a/tools/update_headers.sh b/tools/update_headers.sh
index e5b87f1..0095d50 100755
--- a/tools/update_headers.sh
+++ b/tools/update_headers.sh
@@ -35,11 +35,17 @@
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
cp ../libc/NOTICE $PREBUILTS_DIR