Merge "memset_chk into assembly file"
diff --git a/libc/Android.bp b/libc/Android.bp
index 23b381d..c101f45 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -1092,7 +1092,6 @@
         "bionic/ffs.cpp",
         "bionic/fgetxattr.cpp",
         "bionic/flistxattr.cpp",
-        "bionic/flockfile.cpp",
         "bionic/fpclassify.cpp",
         "bionic/fsetxattr.cpp",
         "bionic/ftruncate.cpp",
diff --git a/libc/arch-common/bionic/crtend.S b/libc/arch-common/bionic/crtend.S
index 9676db8..49c729f 100644
--- a/libc/arch-common/bionic/crtend.S
+++ b/libc/arch-common/bionic/crtend.S
@@ -46,11 +46,10 @@
 	ASM_ALIGN_TO_PTR_SIZE
 	ASM_PTR_SIZE(0)
 
-#if defined(__linux__) && defined(__ELF__)
-	.section .note.GNU-stack,"",%progbits
-#endif
+	.section .note.GNU-stack, "", %progbits
+
 #if !defined(__arm__)
-	.section	.eh_frame,"a",@progbits
+	.section .eh_frame, "a", @progbits
 	.balign 4
 	.type	__FRAME_END__, @object
 	.size	__FRAME_END__, 4
diff --git a/libc/arch-common/bionic/crtend_so.S b/libc/arch-common/bionic/crtend_so.S
index 5875acb..bc4bfb6 100644
--- a/libc/arch-common/bionic/crtend_so.S
+++ b/libc/arch-common/bionic/crtend_so.S
@@ -32,11 +32,10 @@
 __bionic_asm_custom_note_gnu_section()
 #endif
 
-#if defined(__linux__) && defined(__ELF__)
-	.section .note.GNU-stack,"",%progbits
-#endif
+	.section .note.GNU-stack, "", %progbits
+
 #if !defined(__arm__)
-	.section	.eh_frame,"a",@progbits
+	.section .eh_frame, "a", @progbits
 	.balign 4
 	.type	__FRAME_END__, @object
 	.size	__FRAME_END__, 4
diff --git a/libc/bionic/flockfile.cpp b/libc/bionic/flockfile.cpp
deleted file mode 100644
index db53828..0000000
--- a/libc/bionic/flockfile.cpp
+++ /dev/null
@@ -1,58 +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.
- */
-
-#include <errno.h>
-#include <stdio.h>
-
-#include "local.h"
-
-// We can't use the OpenBSD implementation which uses kernel-specific
-// APIs not available on Linux. Instead we use a pthread_mutex_t within
-// struct __sfileext (see fileext.h).
-
-void flockfile(FILE* fp) {
-  if (fp != nullptr) {
-    pthread_mutex_lock(&_FLOCK(fp));
-  }
-}
-
-int ftrylockfile(FILE* fp) {
-  // The specification for ftrylockfile() says it returns 0 on success,
-  // or non-zero on error. So return an errno code directly on error.
-  if (fp == nullptr) {
-    return EINVAL;
-  }
-
-  return pthread_mutex_trylock(&_FLOCK(fp));
-}
-
-void funlockfile(FILE* fp) {
-  if (fp != nullptr) {
-    pthread_mutex_unlock(&_FLOCK(fp));
-  }
-}
diff --git a/libc/include/dlfcn.h b/libc/include/dlfcn.h
index 68d8bc9..a8066a9 100644
--- a/libc/include/dlfcn.h
+++ b/libc/include/dlfcn.h
@@ -36,21 +36,23 @@
 
 typedef struct {
   /* Pathname of shared object that contains address. */
-  const char* dli_fname;
+  const char* _Nullable dli_fname;
   /* Address at which shared object is loaded. */
-  void* dli_fbase;
+  void* _Nullable dli_fbase;
   /* Name of nearest symbol with address lower than addr. */
-  const char* dli_sname;
+  const char* _Nullable dli_sname;
   /* Exact address of symbol named in dli_sname. */
-  void* dli_saddr;
+  void* _Nullable dli_saddr;
 } Dl_info;
 
-void* dlopen(const char* __filename, int __flag);
-int dlclose(void* __handle);
-char* dlerror(void);
-void* dlsym(void* __handle, const char* __symbol);
-void* dlvsym(void* __handle, const char* __symbol, const char* __version) __INTRODUCED_IN(24);
-int dladdr(const void* __addr, Dl_info* __info);
+void* _Nullable dlopen(const char* _Nullable __filename, int __flag);
+int dlclose(void* _Nonnull __handle);
+char* _Nullable dlerror(void);
+/* (RTLD_DEFAULT is null for LP64, but -1 for LP32) */
+void* _Nullable dlsym(void* __BIONIC_COMPLICATED_NULLNESS __handle, const char* _Nullable __symbol);
+/* (RTLD_DEFAULT is null for LP64, but -1 for LP32) */
+void* _Nullable dlvsym(void* __BIONIC_COMPLICATED_NULLNESS __handle, const char* _Nullable __symbol, const char* _Nullable __version) __INTRODUCED_IN(24);
+int dladdr(const void* _Nonnull __addr, Dl_info* _Nonnull __info);
 
 #define RTLD_LOCAL    0
 #define RTLD_LAZY     0x00001
diff --git a/libc/stdio/local.h b/libc/stdio/local.h
index 6ffda49..2fc12a0 100644
--- a/libc/stdio/local.h
+++ b/libc/stdio/local.h
@@ -170,7 +170,6 @@
 #define _EXT(fp) __BIONIC_CAST(reinterpret_cast, struct __sfileext*, (fp)->_ext._base)
 
 #define _UB(fp) _EXT(fp)->_ub
-#define _FLOCK(fp) _EXT(fp)->_lock
 
 #define _FILEEXT_SETUP(fp, fext)                                              \
   do {                                                                        \
diff --git a/libc/stdio/stdio.cpp b/libc/stdio/stdio.cpp
index 27813a6..645aefa 100644
--- a/libc/stdio/stdio.cpp
+++ b/libc/stdio/stdio.cpp
@@ -197,7 +197,7 @@
 	fp->_lb._size = 0;
 
 	memset(_EXT(fp), 0, sizeof(struct __sfileext));
-	_FLOCK(fp) = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+	_EXT(fp)->_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
 	_EXT(fp)->_caller_handles_locking = false;
 
 	// Caller sets cookie, _read/_write etc.
@@ -884,7 +884,7 @@
 
 void perror(const char* msg) {
   if (msg == nullptr) msg = "";
-  fprintf(stderr, "%s%s%s\n", msg, (*msg == '\0') ? "" : ": ", strerror(errno));
+  fprintf(stderr, "%s%s%m\n", msg, (*msg == '\0') ? "" : ": ");
 }
 
 int printf(const char* fmt, ...) {
@@ -1239,6 +1239,23 @@
   return __FILE_close(fp);
 }
 
+void flockfile(FILE* fp) {
+  CHECK_FP(fp);
+  pthread_mutex_lock(&_EXT(fp)->_lock);
+}
+
+int ftrylockfile(FILE* fp) {
+  CHECK_FP(fp);
+  // The specification for ftrylockfile() says it returns 0 on success,
+  // or non-zero on error. We don't bother canonicalizing to 0/-1...
+  return pthread_mutex_trylock(&_EXT(fp)->_lock);
+}
+
+void funlockfile(FILE* fp) {
+  CHECK_FP(fp);
+  pthread_mutex_unlock(&_EXT(fp)->_lock);
+}
+
 namespace {
 
 namespace phony {
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index 939c092..3f70279 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -889,11 +889,14 @@
   void* sym;
 
 #if defined(__BIONIC__) && !defined(__LP64__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
   // RTLD_DEFAULT in lp32 bionic is not (void*)0
   // so it can be distinguished from the NULL handle.
   sym = dlsym(nullptr, "test");
   ASSERT_TRUE(sym == nullptr);
   ASSERT_STREQ("dlsym failed: library handle is null", dlerror());
+#pragma clang diagnostic pop
 #endif
 
   // Symbol that doesn't exist.
@@ -1008,9 +1011,12 @@
 
   dlerror(); // Clear any pending errors.
 
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnonnull"
   // No symbol corresponding to NULL.
   ASSERT_EQ(dladdr(nullptr, &info), 0); // Zero on error, non-zero on success.
   ASSERT_TRUE(dlerror() == nullptr); // dladdr(3) doesn't set dlerror(3).
+#pragma clang diagnostic pop
 
   // No symbol corresponding to a stack address.
   ASSERT_EQ(dladdr(&info, &info), 0); // Zero on error, non-zero on success.
diff --git a/tests/elftls_dl_test.cpp b/tests/elftls_dl_test.cpp
index 82ccf82..56736e7 100644
--- a/tests/elftls_dl_test.cpp
+++ b/tests/elftls_dl_test.cpp
@@ -30,6 +30,7 @@
 #include <link.h>
 
 #include <android-base/file.h>
+#include <android-base/test_utils.h>
 #include <gtest/gtest.h>
 
 #include <thread>
@@ -153,6 +154,7 @@
 }
 
 TEST(elftls_dl, dtv_resize) {
+  SKIP_WITH_HWASAN; // TODO(b/271243811): Fix for new toolchain
 #if defined(__BIONIC__)
 #define LOAD_LIB(soname) ({                           \
     auto lib = dlopen(soname, RTLD_LOCAL | RTLD_NOW); \
diff --git a/tests/gwp_asan_test.cpp b/tests/gwp_asan_test.cpp
index 38661c7..8b12bec 100644
--- a/tests/gwp_asan_test.cpp
+++ b/tests/gwp_asan_test.cpp
@@ -58,13 +58,10 @@
 // the torture mode is is generally 40,000, so that svelte devices don't
 // explode, as this uses ~163MiB RAM (4KiB per live allocation).
 TEST(gwp_asan_integration, malloc_tests_under_torture) {
-  if (running_with_hwasan()) {
-    // Skip the malloc.zeroed tests since they fail in this particular config.
-    // TODO(b/267386540): Need to fix this problem.
-    RunGwpAsanTest("malloc.*:-malloc.mallinfo*:malloc.zeroed*");
-  } else {
-    RunGwpAsanTest("malloc.*:-malloc.mallinfo*");
-  }
+  // Do not override HWASan with GWP ASan.
+  SKIP_WITH_HWASAN;
+
+  RunGwpAsanTest("malloc.*:-malloc.mallinfo*");
 }
 
 class SyspropRestorer {
@@ -153,6 +150,9 @@
 }
 
 TEST(gwp_asan_integration, sysprops_program_specific) {
+  // Do not override HWASan with GWP ASan.
+  SKIP_WITH_HWASAN;
+
   SyspropRestorer restorer;
 
   std::string path = testing::internal::GetArgvs()[0];
@@ -167,6 +167,9 @@
 }
 
 TEST(gwp_asan_integration, sysprops_persist_program_specific) {
+  // Do not override HWASan with GWP ASan.
+  SKIP_WITH_HWASAN;
+
   SyspropRestorer restorer;
 
   std::string path = testing::internal::GetArgvs()[0];
@@ -182,6 +185,9 @@
 }
 
 TEST(gwp_asan_integration, sysprops_system) {
+  // Do not override HWASan with GWP ASan.
+  SKIP_WITH_HWASAN;
+
   SyspropRestorer restorer;
 
   __system_property_set("libc.debug.gwp_asan.sample_rate.system_default", "1");
@@ -192,6 +198,9 @@
 }
 
 TEST(gwp_asan_integration, sysprops_persist_system) {
+  // Do not override HWASan with GWP ASan.
+  SKIP_WITH_HWASAN;
+
   SyspropRestorer restorer;
 
   __system_property_set("persist.libc.debug.gwp_asan.sample_rate.system_default", "1");
@@ -202,6 +211,9 @@
 }
 
 TEST(gwp_asan_integration, sysprops_non_persist_overrides_persist) {
+  // Do not override HWASan with GWP ASan.
+  SKIP_WITH_HWASAN;
+
   SyspropRestorer restorer;
 
   __system_property_set("libc.debug.gwp_asan.sample_rate.system_default", "1");
@@ -216,6 +228,9 @@
 }
 
 TEST(gwp_asan_integration, sysprops_program_specific_overrides_default) {
+  // Do not override HWASan with GWP ASan.
+  SKIP_WITH_HWASAN;
+
   SyspropRestorer restorer;
 
   std::string path = testing::internal::GetArgvs()[0];
@@ -235,6 +250,9 @@
 }
 
 TEST(gwp_asan_integration, sysprops_can_disable) {
+  // Do not override HWASan with GWP ASan.
+  SKIP_WITH_HWASAN;
+
   SyspropRestorer restorer;
 
   __system_property_set("libc.debug.gwp_asan.sample_rate.system_default", "0");
@@ -245,6 +263,9 @@
 }
 
 TEST(gwp_asan_integration, env_overrides_sysprop) {
+  // Do not override HWASan with GWP ASan.
+  SKIP_WITH_HWASAN;
+
   SyspropRestorer restorer;
 
   __system_property_set("libc.debug.gwp_asan.sample_rate.system_default", "0");
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index 907a35c..06a0f3d 100644
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -41,6 +41,7 @@
 #include <android-base/scopeguard.h>
 #include <android-base/silent_death_test.h>
 #include <android-base/strings.h>
+#include <android-base/test_utils.h>
 
 #include "private/bionic_constants.h"
 #include "SignalUtils.h"
@@ -184,6 +185,30 @@
   ASSERT_EQ(0, pthread_key_delete(key));
 }
 
+static void* FnWithStackFrame(void*) {
+  int x;
+  *const_cast<volatile int*>(&x) = 1;
+  return nullptr;
+}
+
+TEST(pthread, pthread_heap_allocated_stack) {
+  SKIP_WITH_HWASAN; // TODO(b/148982147): Re-enable when fixed.
+
+  size_t stack_size = 640 * 1024;
+  std::vector<char> stack_vec(stack_size, '\xff');
+  void* stack = stack_vec.data();
+
+  pthread_attr_t attr;
+  ASSERT_EQ(0, pthread_attr_init(&attr));
+  ASSERT_EQ(0, pthread_attr_setstack(&attr, stack, stack_size));
+
+  pthread_t t;
+  ASSERT_EQ(0, pthread_create(&t, &attr, FnWithStackFrame, nullptr));
+
+  void* result;
+  ASSERT_EQ(0, pthread_join(t, &result));
+}
+
 TEST(pthread, static_pthread_key_used_before_creation) {
 #if defined(__BIONIC__)
   // See http://b/19625804. The bug is about a static/global pthread key being used before creation.