summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2021-07-08 10:44:11 -0700
committerLinux Build Service Account <lnxbuild@localhost>2021-07-08 10:44:11 -0700
commitf15e6f2bda4a5c60ffc5faaafadf4c48c947f5e6 (patch)
tree0b54317ff0c75bef86b4b22e9b997d801a3e606d
parentd810f3683ae5e030bcd656361314895260beffb9 (diff)
parentaf1f724947d8a37c13e6e7163ba35481b8ba4dcc (diff)
Merge af1f724947d8a37c13e6e7163ba35481b8ba4dcc on remote branch
Change-Id: Icd977d266c2e4654e328bec1e08ff704d4287b3e
-rw-r--r--apex/Android.bp1
-rw-r--r--libc/arch-arm/bionic/__bionic_clone.S2
-rw-r--r--libc/arch-common/bionic/crtbegin.c10
-rw-r--r--libc/arch-x86/bionic/__bionic_clone.S1
-rw-r--r--libc/bionic/malloc_heapprofd.cpp10
-rw-r--r--libc/bionic/pthread_create.cpp5
-rw-r--r--libc/dns/resolv/res_cache.c37
-rw-r--r--libc/malloc_debug/PointerData.cpp4
-rw-r--r--libc/malloc_debug/UnwindBacktrace.cpp10
-rw-r--r--tests/dl_test.cpp15
-rw-r--r--tests/stack_unwinding_test.cpp23
11 files changed, 63 insertions, 55 deletions
diff --git a/apex/Android.bp b/apex/Android.bp
index 90a14b245..4879f474c 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -58,6 +58,7 @@ apex {
"bionic-linker-config",
],
updatable: false,
+ generate_hashtree: false,
}
sdk {
diff --git a/libc/arch-arm/bionic/__bionic_clone.S b/libc/arch-arm/bionic/__bionic_clone.S
index 6669b93a2..3fe212b47 100644
--- a/libc/arch-arm/bionic/__bionic_clone.S
+++ b/libc/arch-arm/bionic/__bionic_clone.S
@@ -61,6 +61,8 @@ ENTRY_PRIVATE(__bionic_clone)
b __set_errno_internal
.L_bc_child:
+ # We're in the child now. Set the end of the frame record chain.
+ mov fp, #0
# Setting lr to 0 will make the unwinder stop at __start_thread.
mov lr, #0
# Call __start_thread with the 'fn' and 'arg' we stored on the child stack.
diff --git a/libc/arch-common/bionic/crtbegin.c b/libc/arch-common/bionic/crtbegin.c
index 628783789..5f681c53c 100644
--- a/libc/arch-common/bionic/crtbegin.c
+++ b/libc/arch-common/bionic/crtbegin.c
@@ -49,13 +49,15 @@ __used static void _start_main(void* raw_args) {
#define POST "; .size _start, .-_start"
#if defined(__aarch64__)
-__asm__(PRE "bti j; mov x0,sp; b _start_main" POST);
+__asm__(PRE "bti j; mov x29,#0; mov x30,#0; mov x0,sp; b _start_main" POST);
#elif defined(__arm__)
-__asm__(PRE "mov r0,sp; b _start_main" POST);
+__asm__(PRE "mov fp,#0; mov lr,#0; mov r0,sp; b _start_main" POST);
#elif defined(__i386__)
-__asm__(PRE "movl %esp,%eax; andl $~0xf,%esp; subl $12,%esp; pushl %eax; calll _start_main" POST);
+__asm__(PRE
+ "xorl %ebp,%ebp; movl %esp,%eax; andl $~0xf,%esp; subl $12,%esp; pushl %eax;"
+ "calll _start_main" POST);
#elif defined(__x86_64__)
-__asm__(PRE "movq %rsp,%rdi; andq $~0xf,%rsp; callq _start_main" POST);
+__asm__(PRE "xorl %ebp, %ebp; movq %rsp,%rdi; andq $~0xf,%rsp; callq _start_main" POST);
#else
#error unsupported architecture
#endif
diff --git a/libc/arch-x86/bionic/__bionic_clone.S b/libc/arch-x86/bionic/__bionic_clone.S
index b682b4863..f0c58a00d 100644
--- a/libc/arch-x86/bionic/__bionic_clone.S
+++ b/libc/arch-x86/bionic/__bionic_clone.S
@@ -45,6 +45,7 @@ ENTRY_PRIVATE(__bionic_clone)
.L_bc_child:
# We don't want anyone to unwind past this point.
.cfi_undefined %eip
+ .cfi_undefined %ebp
call __start_thread
hlt
diff --git a/libc/bionic/malloc_heapprofd.cpp b/libc/bionic/malloc_heapprofd.cpp
index 198bcbab7..741b45e98 100644
--- a/libc/bionic/malloc_heapprofd.cpp
+++ b/libc/bionic/malloc_heapprofd.cpp
@@ -325,12 +325,12 @@ void HeapprofdRememberHookConflict() {
static void CommonInstallHooks(libc_globals* globals) {
void* impl_handle = atomic_load(&gHeapprofdHandle);
- bool reusing_handle = impl_handle != nullptr;
- if (!reusing_handle) {
+ if (impl_handle == nullptr) {
impl_handle = LoadSharedLibrary(kHeapprofdSharedLib, kHeapprofdPrefix, &globals->malloc_dispatch_table);
if (impl_handle == nullptr) {
return;
}
+ atomic_store(&gHeapprofdHandle, impl_handle);
} else if (!InitSharedLibrary(impl_handle, kHeapprofdSharedLib, kHeapprofdPrefix, &globals->malloc_dispatch_table)) {
return;
}
@@ -341,11 +341,7 @@ static void CommonInstallHooks(libc_globals* globals) {
// MaybeModifyGlobals locks at this point.
atomic_store(&gPreviousDefaultDispatchTable, GetDefaultDispatchTable());
- if (FinishInstallHooks(globals, nullptr, kHeapprofdPrefix)) {
- atomic_store(&gHeapprofdHandle, impl_handle);
- } else if (!reusing_handle) {
- dlclose(impl_handle);
- }
+ FinishInstallHooks(globals, nullptr, kHeapprofdPrefix);
}
void HeapprofdInstallHooksAtInit(libc_globals* globals) {
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index 46d9e8672..121b26f82 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -331,6 +331,11 @@ void __set_stack_and_tls_vma_name(bool is_main_thread) {
extern "C" int __rt_sigprocmask(int, const sigset64_t*, sigset64_t*, size_t);
__attribute__((no_sanitize("hwaddress")))
+#ifdef __aarch64__
+// This function doesn't return, but it does appear in stack traces. Avoid using return PAC in this
+// function because we may end up resetting IA, which may confuse unwinders due to mismatching keys.
+__attribute__((target("branch-protection=bti")))
+#endif
static int __pthread_start(void* arg) {
pthread_internal_t* thread = reinterpret_cast<pthread_internal_t*>(arg);
diff --git a/libc/dns/resolv/res_cache.c b/libc/dns/resolv/res_cache.c
index c1c2059ef..f4c590f60 100644
--- a/libc/dns/resolv/res_cache.c
+++ b/libc/dns/resolv/res_cache.c
@@ -28,7 +28,6 @@
#include "resolv_cache.h"
-#include <ctype.h>
#include <resolv.h>
#include <stdarg.h>
#include <stdio.h>
@@ -454,22 +453,6 @@ typedef struct {
const uint8_t* cursor;
} DnsPacket;
-static int
-memcasecmp( const unsigned char *s1, const unsigned char *s2, int len )
-{
- for ( int i = 0; i < len; i++ )
- {
- int ch1 = *s1++;
- int ch2 = *s2++;
- int d = tolower(ch1) - tolower(ch2);
- if (d != 0)
- {
- return d;
- }
- }
- return 0;
-}
-
static void
_dnsPacket_init( DnsPacket* packet, const uint8_t* buff, int bufflen )
{
@@ -782,7 +765,6 @@ _dnsPacket_hashBytes( DnsPacket* packet, int numBytes, unsigned hash )
while (numBytes > 0 && p < end) {
hash = hash*FNV_MULT ^ *p++;
- numBytes -= 1;
}
packet->cursor = p;
return hash;
@@ -796,12 +778,14 @@ _dnsPacket_hashQName( DnsPacket* packet, unsigned hash )
const uint8_t* end = packet->end;
for (;;) {
+ int c;
+
if (p >= end) { /* should not happen */
XLOG("%s: INTERNAL_ERROR: read-overflow !!\n", __FUNCTION__);
break;
}
- int c = *p++;
+ c = *p++;
if (c == 0)
break;
@@ -815,12 +799,9 @@ _dnsPacket_hashQName( DnsPacket* packet, unsigned hash )
__FUNCTION__);
break;
}
-
while (c > 0) {
- int ch = *p++;
- ch = tolower(ch);
- hash = hash * (FNV_MULT ^ ch);
- c--;
+ hash = hash*FNV_MULT ^ *p++;
+ c -= 1;
}
}
packet->cursor = p;
@@ -907,12 +888,14 @@ _dnsPacket_isEqualDomainName( DnsPacket* pack1, DnsPacket* pack2 )
const uint8_t* end2 = pack2->end;
for (;;) {
+ int c1, c2;
+
if (p1 >= end1 || p2 >= end2) {
XLOG("%s: INTERNAL_ERROR: read-overflow !!\n", __FUNCTION__);
break;
}
- int c1 = *p1++;
- int c2 = *p2++;
+ c1 = *p1++;
+ c2 = *p2++;
if (c1 != c2)
break;
@@ -930,7 +913,7 @@ _dnsPacket_isEqualDomainName( DnsPacket* pack1, DnsPacket* pack2 )
__FUNCTION__);
break;
}
- if (memcasecmp(p1, p2, c1) != 0)
+ if (memcmp(p1, p2, c1) != 0)
break;
p1 += c1;
p2 += c1;
diff --git a/libc/malloc_debug/PointerData.cpp b/libc/malloc_debug/PointerData.cpp
index a15b1b13a..4c5559bb9 100644
--- a/libc/malloc_debug/PointerData.cpp
+++ b/libc/malloc_debug/PointerData.cpp
@@ -591,8 +591,8 @@ void PointerData::DumpLiveToFile(int fd) {
dprintf(fd, " bt_info");
for (const auto& frame : *info.backtrace_info) {
dprintf(fd, " {");
- if (frame.map_info != nullptr && !frame.map_info->name.empty()) {
- dprintf(fd, "\"%s\"", frame.map_info->name.c_str());
+ if (frame.map_info != nullptr && !frame.map_info->name().empty()) {
+ dprintf(fd, "\"%s\"", frame.map_info->name().c_str());
} else {
dprintf(fd, "\"\"");
}
diff --git a/libc/malloc_debug/UnwindBacktrace.cpp b/libc/malloc_debug/UnwindBacktrace.cpp
index 92fb3fa96..128991bd9 100644
--- a/libc/malloc_debug/UnwindBacktrace.cpp
+++ b/libc/malloc_debug/UnwindBacktrace.cpp
@@ -90,14 +90,14 @@ void UnwindLog(const std::vector<unwindstack::LocalFrameData>& frame_info) {
unwindstack::MapInfo* map_info = info->map_info;
std::string line = android::base::StringPrintf(" #%0zd pc %" PAD_PTR " ", i, info->rel_pc);
- if (map_info->offset != 0) {
- line += android::base::StringPrintf("(offset 0x%" PRIx64 ") ", map_info->offset);
+ if (map_info->offset() != 0) {
+ line += android::base::StringPrintf("(offset 0x%" PRIx64 ") ", map_info->offset());
}
- if (map_info->name.empty()) {
- line += android::base::StringPrintf("<anonymous:%" PRIx64 ">", map_info->start);
+ if (map_info->name().empty()) {
+ line += android::base::StringPrintf("<anonymous:%" PRIx64 ">", map_info->start());
} else {
- line += map_info->name;
+ line += map_info->name();
}
if (!info->function_name.empty()) {
diff --git a/tests/dl_test.cpp b/tests/dl_test.cpp
index 766f27a0b..47bf13374 100644
--- a/tests/dl_test.cpp
+++ b/tests/dl_test.cpp
@@ -264,8 +264,11 @@ static void create_ld_config_file(const char* config_file) {
#endif
#if defined(__BIONIC__)
-static bool is_debuggable_build() {
- return android::base::GetBoolProperty("ro.debuggable", false);
+// This test can't rely on ro.debuggable, because it might have been forced on
+// in a user build ("Force Debuggable"). In that configuration, ro.debuggable is
+// true, but Bionic's LD_CONFIG_FILE testing support is still disabled.
+static bool is_user_build() {
+ return android::base::GetProperty("ro.build.type", "user") == std::string("user");
}
#endif
@@ -282,7 +285,7 @@ static bool is_debuggable_build() {
TEST(dl, exec_with_ld_config_file) {
#if defined(__BIONIC__)
SKIP_WITH_HWASAN << "libclang_rt.hwasan is not found with custom ld config";
- if (!is_debuggable_build()) {
+ if (is_user_build()) {
GTEST_SKIP() << "LD_CONFIG_FILE is not supported on user build";
}
std::string helper = GetTestlibRoot() +
@@ -319,7 +322,7 @@ TEST(dl, exec_with_ld_config_file) {
TEST(dl, exec_with_ld_config_file_with_ld_preload) {
#if defined(__BIONIC__)
SKIP_WITH_HWASAN << "libclang_rt.hwasan is not found with custom ld config";
- if (!is_debuggable_build()) {
+ if (is_user_build()) {
GTEST_SKIP() << "LD_CONFIG_FILE is not supported on user build";
}
std::string helper = GetTestlibRoot() +
@@ -356,8 +359,8 @@ TEST(dl, disable_ld_config_file) {
// This test is only for CTS.
GTEST_SKIP() << "test is not supported with root uid";
}
- if (is_debuggable_build()) {
- GTEST_SKIP() << "test is not supported on debuggable build";
+ if (!is_user_build()) {
+ GTEST_SKIP() << "test requires user build";
}
std::string error_message = std::string("CANNOT LINK EXECUTABLE ") +
diff --git a/tests/stack_unwinding_test.cpp b/tests/stack_unwinding_test.cpp
index 0ff6f30a6..2f891a6e1 100644
--- a/tests/stack_unwinding_test.cpp
+++ b/tests/stack_unwinding_test.cpp
@@ -66,13 +66,28 @@ static int noinline unwind_one_frame_deeper() {
return count;
}
-TEST(stack_unwinding, easy) {
+static void UnwindTest() {
int count = 0;
_Unwind_Backtrace(FrameCounter, &count);
int deeper_count = unwind_one_frame_deeper();
ASSERT_EQ(count + 1, deeper_count);
}
+TEST(stack_unwinding, easy) {
+ UnwindTest();
+}
+
+TEST(stack_unwinding, thread) {
+ pthread_t thread;
+ ASSERT_EQ(0, pthread_create(&thread, nullptr, [](void*) -> void* {
+ UnwindTest();
+ return nullptr;
+ }, nullptr));
+ void *retval;
+ ASSERT_EQ(0, pthread_join(thread, &retval));
+ EXPECT_EQ(nullptr, retval);
+}
+
struct UnwindData {
volatile bool signal_handler_complete = false;
int expected_frame_count = 0;
@@ -98,7 +113,7 @@ static void verify_unwind_data(const UnwindData& unwind_data) {
EXPECT_EQ(unwind_data.handler_frame_count + 1, unwind_data.handler_one_deeper_frame_count);
}
-static void noinline UnwindTest() {
+static void noinline SignalUnwindTest() {
g_unwind_data = {};
_Unwind_Backtrace(FrameCounter, &g_unwind_data.expected_frame_count);
@@ -114,12 +129,12 @@ static void noinline UnwindTest() {
TEST(stack_unwinding, unwind_through_signal_frame) {
ScopedSignalHandler ssh(SIGUSR1, UnwindSignalHandler);
- UnwindTest();
+ SignalUnwindTest();
}
// On LP32, the SA_SIGINFO flag gets you __restore_rt instead of __restore.
TEST(stack_unwinding, unwind_through_signal_frame_SA_SIGINFO) {
ScopedSignalHandler ssh(SIGUSR1, UnwindSignalHandler, SA_SIGINFO);
- UnwindTest();
+ SignalUnwindTest();
}