Disable return PAC in __pthread_start.

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.

Bug: 189808795
Change-Id: I953da9078acd1d43eb7a47fb11f75caa0099fa12
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index 46d9e86..121b26f 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -331,6 +331,11 @@
 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/tests/stack_unwinding_test.cpp b/tests/stack_unwinding_test.cpp
index 0ff6f30..2f891a6 100644
--- a/tests/stack_unwinding_test.cpp
+++ b/tests/stack_unwinding_test.cpp
@@ -66,13 +66,28 @@
   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 @@
   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 @@
 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();
 }