Merge "Fix out-of-bounds deque access causing build failure."
diff --git a/libc/arch-arm/generic/bionic/strlen.c b/libc/arch-arm/generic/bionic/strlen.c
index f6b9209..dccd564 100644
--- a/libc/arch-arm/generic/bionic/strlen.c
+++ b/libc/arch-arm/generic/bionic/strlen.c
@@ -67,53 +67,46 @@
"sub %[t], %[v], %[mask], lsr #7\n"
"and %[t], %[t], %[mask] \n"
"bics %[t], %[t], %[v] \n"
- "it eq \n"
- "ldreq %[v], [%[s]], #4 \n"
+ "bne 1f \n"
+ "ldr %[v], [%[s]], #4 \n"
#if !defined(__OPTIMIZE_SIZE__)
- "bne 1f \n"
"sub %[t], %[v], %[mask], lsr #7\n"
"and %[t], %[t], %[mask] \n"
"bics %[t], %[t], %[v] \n"
- "it eq \n"
- "ldreq %[v], [%[s]], #4 \n"
"bne 1f \n"
+ "ldr %[v], [%[s]], #4 \n"
"sub %[t], %[v], %[mask], lsr #7\n"
"and %[t], %[t], %[mask] \n"
"bics %[t], %[t], %[v] \n"
- "it eq \n"
- "ldreq %[v], [%[s]], #4 \n"
"bne 1f \n"
+ "ldr %[v], [%[s]], #4 \n"
"sub %[t], %[v], %[mask], lsr #7\n"
"and %[t], %[t], %[mask] \n"
"bics %[t], %[t], %[v] \n"
- "it eq \n"
- "ldreq %[v], [%[s]], #4 \n"
"bne 1f \n"
+ "ldr %[v], [%[s]], #4 \n"
"sub %[t], %[v], %[mask], lsr #7\n"
"and %[t], %[t], %[mask] \n"
"bics %[t], %[t], %[v] \n"
- "it eq \n"
- "ldreq %[v], [%[s]], #4 \n"
"bne 1f \n"
+ "ldr %[v], [%[s]], #4 \n"
"sub %[t], %[v], %[mask], lsr #7\n"
"and %[t], %[t], %[mask] \n"
"bics %[t], %[t], %[v] \n"
- "it eq \n"
- "ldreq %[v], [%[s]], #4 \n"
"bne 1f \n"
+ "ldr %[v], [%[s]], #4 \n"
"sub %[t], %[v], %[mask], lsr #7\n"
"and %[t], %[t], %[mask] \n"
"bics %[t], %[t], %[v] \n"
- "it eq \n"
- "ldreq %[v], [%[s]], #4 \n"
"bne 1f \n"
+ "ldr %[v], [%[s]], #4 \n"
"sub %[t], %[v], %[mask], lsr #7\n"
"and %[t], %[t], %[mask] \n"
"bics %[t], %[t], %[v] \n"
- "it eq \n"
- "ldreq %[v], [%[s]], #4 \n"
+ "bne 1f \n"
+ "ldr %[v], [%[s]], #4 \n"
#endif
- "beq 0b \n"
+ "b 0b \n"
"1: \n"
"add %[l], %[l], %[s] \n"
"tst %[v], #0xFF \n"
diff --git a/libc/include/string.h b/libc/include/string.h
index 631b3dd..164146d 100644
--- a/libc/include/string.h
+++ b/libc/include/string.h
@@ -58,8 +58,11 @@
char* __strchr_chk(const char*, int, size_t) __INTRODUCED_IN(18);
#if defined(__USE_GNU)
#if defined(__cplusplus)
+/* The versioner doesn't handle C++ blocks yet, so manually guarded. */
+#if __ANDROID_API__ >= 24
extern "C++" char* strchrnul(char*, int) __RENAME(strchrnul) __attribute_pure__ __INTRODUCED_IN(24);
extern "C++" const char* strchrnul(const char*, int) __RENAME(strchrnul) __attribute_pure__ __INTRODUCED_IN(24);
+#endif /* __ANDROID_API__ >= 24 */
#else
char* strchrnul(const char*, int) __attribute_pure__ __INTRODUCED_IN(24);
#endif
@@ -125,8 +128,11 @@
* It doesn't modify its argument, and in C++ it's const-correct.
*/
#if defined(__cplusplus)
+/* The versioner doesn't handle C++ blocks yet, so manually guarded. */
+#if __ANDROID_API__ >= 23
extern "C++" char* basename(char*) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
extern "C++" const char* basename(const char*) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
+#endif /* __ANDROID_API__ >= 23 */
#else
char* basename(const char*) __RENAME(__gnu_basename) __INTRODUCED_IN(23);
#endif
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index 9541520..71d8426 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -239,7 +239,8 @@
#define __BIONIC_FORTIFY_UNKNOWN_SIZE ((size_t) -1)
-#if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 && defined(__OPTIMIZE__) && __OPTIMIZE__ > 0
+#if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 && \
+ (defined(__clang__) || (defined(__OPTIMIZE__) && __OPTIMIZE__ > 0))
# define __BIONIC_FORTIFY 1
# if _FORTIFY_SOURCE == 2
# define __bos_level 1
@@ -281,8 +282,7 @@
#define __pass_object_size __pass_object_size_n(__bos_level)
#define __pass_object_size0 __pass_object_size_n(0)
-/* FIXME: This should be __BIONIC_FORTIFY, but we don't enable FORTIFY in -O0. */
-#if (defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0) || defined(__BIONIC_DECLARE_FORTIFY_HELPERS)
+#if defined(__BIONIC_FORTIFY) || defined(__BIONIC_DECLARE_FORTIFY_HELPERS)
# define __BIONIC_INCLUDE_FORTIFY_HEADERS 1
#endif
diff --git a/libc/malloc_debug/README.md b/libc/malloc_debug/README.md
index b77af6d..03a8a73 100644
--- a/libc/malloc_debug/README.md
+++ b/libc/malloc_debug/README.md
@@ -371,6 +371,9 @@
Examples
========
+
+### For platform developers
+
Enable backtrace tracking of all allocation for all processes:
adb shell stop
@@ -427,17 +430,7 @@
but, obviously, it must be enabled through the signal before the file will
contain any data.
-To analyze the data produced by the dumpheap command, run this script:
-
- development/scripts/native_heapdump_viewer.py
-
-In order for the script to properly symbolize the stacks in the file,
-make sure the script is executed from the tree that built the image.
-Below is an example of how to execute the script using the dump created by the
-above command:
-
- adb shell pull /data/local/tmp/heap.txt .
- development/scripts/native_heapdump_viewer.py heap.txt > heap_info.txt
+### For app developers
Enable malloc debug for a specific program/application (Android O or later):
@@ -453,3 +446,40 @@
was necessary to truncate the name to fit. On O, property names can be
an order of magnitude larger, so there should be no need to truncate the name
at all.
+
+To detect leaks while an app is running:
+
+ adb shell dumpsys meminfo --unreachable <PID_OF_APP>
+
+Without also enabling malloc debug, this command will only tell
+you whether it can detect leaked memory, not where those leaks are
+occurring. If you enable malloc debug with the backtrace option for your
+app before running the dumpsys command, you'll get backtraces showing
+where the memory was allocated.
+
+For backtraces from your app to be useful, you'll want to keep the
+symbols in your app's shared libraries rather than stripping them. That
+way you'll see the location of the leak directly without having to use
+something like the <code>ndk-stack</code> tool.
+
+### Analyzing heap dumps
+
+To analyze the data produced by the dumpheap command, run this script:
+
+ development/scripts/native_heapdump_viewer.py
+
+In order for the script to properly symbolize the stacks in the file,
+make sure the script is executed from the tree that built the image.
+
+To collect, transfer, and analyze a dump:
+
+ adb shell am dumpheap -n <PID_TO_DUMP> /data/local/tmp/heap.txt
+ adb shell pull /data/local/tmp/heap.txt .
+ python development/scripts/native_heapdump_viewer.py --symbols /some/path/to/symbols/ heap.txt > heap_info.txt
+
+At the moment, the script will look for symbols in the given directory,
+using the path the .so file would have on the device. So if your .so file
+is at `/data/app/.../lib/arm/libx.so` on the device, it will need to be at
+`/some/path/to/symbols/data/app/.../lib/arm/libx.so` locally given the
+command line above. That is: you need to mirror the directory structure
+for the app in the symbols directory.
diff --git a/libc/private/CFIShadow.h b/libc/private/CFIShadow.h
index 26351db..1423d86 100644
--- a/libc/private/CFIShadow.h
+++ b/libc/private/CFIShadow.h
@@ -61,10 +61,8 @@
// Alignment of __cfi_check.
static constexpr uintptr_t kCfiCheckAlign = 1UL << kCfiCheckGranularity; // 4K
-#if defined(__aarch64__)
- static constexpr uintptr_t kMaxTargetAddr = 0x7fffffffff;
-#elif defined (__LP64__)
- static constexpr uintptr_t kMaxTargetAddr = 0x7fffffffffff;
+#if defined (__LP64__)
+ static constexpr uintptr_t kMaxTargetAddr = 0xffffffffffff;
#else
static constexpr uintptr_t kMaxTargetAddr = 0xffffffff;
#endif
diff --git a/libdl/libdl.arm.map b/libdl/libdl.arm.map
index 292bd97..9fc9d23 100644
--- a/libdl/libdl.arm.map
+++ b/libdl/libdl.arm.map
@@ -36,6 +36,7 @@
LIBC_OMR1 { # future
global:
+ __cfi_shadow_size; # future
__cfi_slowpath; # future
__cfi_slowpath_diag; # future
} LIBC_N;
diff --git a/libdl/libdl.arm64.map b/libdl/libdl.arm64.map
index 2fe2c7b..bde6cab 100644
--- a/libdl/libdl.arm64.map
+++ b/libdl/libdl.arm64.map
@@ -35,6 +35,7 @@
LIBC_OMR1 { # future
global:
+ __cfi_shadow_size; # future
__cfi_slowpath; # future
__cfi_slowpath_diag; # future
} LIBC_N;
diff --git a/libdl/libdl.map.txt b/libdl/libdl.map.txt
index 408d4dc..d1f4ab8 100644
--- a/libdl/libdl.map.txt
+++ b/libdl/libdl.map.txt
@@ -35,6 +35,7 @@
LIBC_OMR1 { # future
global:
+ __cfi_shadow_size; # future
__cfi_slowpath; # future
__cfi_slowpath_diag; # future
} LIBC_N;
diff --git a/libdl/libdl.mips.map b/libdl/libdl.mips.map
index 2fe2c7b..bde6cab 100644
--- a/libdl/libdl.mips.map
+++ b/libdl/libdl.mips.map
@@ -35,6 +35,7 @@
LIBC_OMR1 { # future
global:
+ __cfi_shadow_size; # future
__cfi_slowpath; # future
__cfi_slowpath_diag; # future
} LIBC_N;
diff --git a/libdl/libdl.mips64.map b/libdl/libdl.mips64.map
index 2fe2c7b..bde6cab 100644
--- a/libdl/libdl.mips64.map
+++ b/libdl/libdl.mips64.map
@@ -35,6 +35,7 @@
LIBC_OMR1 { # future
global:
+ __cfi_shadow_size; # future
__cfi_slowpath; # future
__cfi_slowpath_diag; # future
} LIBC_N;
diff --git a/libdl/libdl.x86.map b/libdl/libdl.x86.map
index 2fe2c7b..bde6cab 100644
--- a/libdl/libdl.x86.map
+++ b/libdl/libdl.x86.map
@@ -35,6 +35,7 @@
LIBC_OMR1 { # future
global:
+ __cfi_shadow_size; # future
__cfi_slowpath; # future
__cfi_slowpath_diag; # future
} LIBC_N;
diff --git a/libdl/libdl.x86_64.map b/libdl/libdl.x86_64.map
index 2fe2c7b..bde6cab 100644
--- a/libdl/libdl.x86_64.map
+++ b/libdl/libdl.x86_64.map
@@ -35,6 +35,7 @@
LIBC_OMR1 { # future
global:
+ __cfi_shadow_size; # future
__cfi_slowpath; # future
__cfi_slowpath_diag; # future
} LIBC_N;
diff --git a/libdl/libdl_cfi.cpp b/libdl/libdl_cfi.cpp
index 8458564..483364f 100644
--- a/libdl/libdl_cfi.cpp
+++ b/libdl/libdl_cfi.cpp
@@ -38,6 +38,11 @@
return &shadow_base_storage.v;
}
+// Returns the size of the CFI shadow mapping, or 0 if CFI is not (yet) used in this process.
+extern "C" size_t __cfi_shadow_size() {
+ return shadow_base_storage.v != 0 ? CFIShadow::kShadowSize : 0;
+}
+
static uint16_t shadow_load(void* p) {
uintptr_t addr = reinterpret_cast<uintptr_t>(p);
uintptr_t ofs = CFIShadow::MemToShadowOffset(addr);
diff --git a/linker/linker.cpp b/linker/linker.cpp
index a212624..8aadd14 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -3506,6 +3506,9 @@
g_default_namespace.set_permitted_paths(default_ns_config->permitted_paths());
namespaces[default_ns_config->name()] = &g_default_namespace;
+ if (default_ns_config->visible()) {
+ g_exported_namespaces[default_ns_config->name()] = &g_default_namespace;
+ }
// 2. Initialize other namespaces
diff --git a/tests/cfi_test.cpp b/tests/cfi_test.cpp
index 5e627a7..088dda6 100644
--- a/tests/cfi_test.cpp
+++ b/tests/cfi_test.cpp
@@ -26,6 +26,7 @@
extern "C" {
void __cfi_slowpath(uint64_t CallSiteTypeId, void* Ptr);
void __cfi_slowpath_diag(uint64_t CallSiteTypeId, void* Ptr, void* DiagData);
+size_t __cfi_shadow_size();
}
static void f() {}
@@ -36,6 +37,8 @@
handle = dlopen("libcfi-test.so", RTLD_NOW | RTLD_LOCAL);
ASSERT_TRUE(handle != nullptr) << dlerror();
+ EXPECT_NE(0U, __cfi_shadow_size());
+
#define SYM(type, name) auto name = reinterpret_cast<type>(dlsym(handle, #name))
SYM(int (*)(), get_count);
SYM(uint64_t(*)(), get_last_type_id);
diff --git a/tools/versioner/src/Driver.cpp b/tools/versioner/src/Driver.cpp
index a094818..8a8e00a 100644
--- a/tools/versioner/src/Driver.cpp
+++ b/tools/versioner/src/Driver.cpp
@@ -119,7 +119,14 @@
cmd.push_back("-DANDROID");
cmd.push_back("-D__ANDROID_API__="s + std::to_string(type.api_level));
+ // FIXME: Re-enable FORTIFY properly once our clang in external/ is new enough
+ // to support diagnose_if without giving us syntax errors.
+#if 0
cmd.push_back("-D_FORTIFY_SOURCE=2");
+#else
+ cmd.push_back("-D_FORTIFY_SOURCE=0");
+ cmd.push_back("-D__BIONIC_DECLARE_FORTIFY_HELPERS");
+#endif
cmd.push_back("-D_GNU_SOURCE");
cmd.push_back("-D_FILE_OFFSET_BITS="s + std::to_string(type.file_offset_bits));