Merge "Add additional dl_phdr_info fields"
diff --git a/libc/bionic/fdsan.cpp b/libc/bionic/fdsan.cpp
index dd3a96e..4ebc796 100644
--- a/libc/bionic/fdsan.cpp
+++ b/libc/bionic/fdsan.cpp
@@ -106,30 +106,8 @@
 }
 
 void __libc_init_fdsan() {
-  constexpr auto default_level = ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE;
-  const prop_info* pi = __system_property_find(kFdsanPropertyName);
-  if (!pi) {
-    android_fdsan_set_error_level(default_level);
-    return;
-  }
-  __system_property_read_callback(
-      pi,
-      [](void*, const char*, const char* value, uint32_t) {
-        if (strcasecmp(value, "1") == 0 || strcasecmp(value, "fatal") == 0) {
-          android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_FATAL);
-        } else if (strcasecmp(value, "warn") == 0) {
-          android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ALWAYS);
-        } else if (strcasecmp(value, "warn_once") == 0) {
-          android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE);
-        } else {
-          if (strlen(value) != 0 && strcasecmp(value, "0") != 0) {
-            async_safe_format_log(ANDROID_LOG_ERROR, "libc",
-                                  "debug.fdsan set to unknown value '%s', disabling", value);
-          }
-          android_fdsan_set_error_level(default_level);
-        }
-      },
-      nullptr);
+  constexpr auto default_level = ANDROID_FDSAN_ERROR_LEVEL_FATAL;
+  android_fdsan_set_error_level_from_property(default_level);
 }
 
 static FdTable& GetFdTable() {
@@ -355,6 +333,45 @@
   return atomic_exchange(&GetFdTable().error_level, new_level);
 }
 
+android_fdsan_error_level android_fdsan_set_error_level_from_property(
+    android_fdsan_error_level default_level) {
+  const prop_info* pi = __system_property_find(kFdsanPropertyName);
+  if (!pi) {
+    return android_fdsan_set_error_level(default_level);
+  }
+
+  struct callback_data {
+    android_fdsan_error_level default_value;
+    android_fdsan_error_level result;
+  };
+
+  callback_data data;
+  data.default_value = default_level;
+
+  __system_property_read_callback(
+      pi,
+      [](void* arg, const char*, const char* value, uint32_t) {
+        callback_data* data = static_cast<callback_data*>(arg);
+
+        if (strcasecmp(value, "1") == 0 || strcasecmp(value, "fatal") == 0) {
+          data->result = android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_FATAL);
+        } else if (strcasecmp(value, "warn") == 0) {
+          data->result = android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ALWAYS);
+        } else if (strcasecmp(value, "warn_once") == 0) {
+          data->result = android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE);
+        } else {
+          if (strlen(value) != 0 && strcasecmp(value, "0") != 0) {
+            async_safe_format_log(ANDROID_LOG_ERROR, "libc",
+                                  "debug.fdsan set to unknown value '%s', disabling", value);
+          }
+          data->result = android_fdsan_set_error_level(data->default_value);
+        }
+      },
+      &data);
+
+  return data.result;
+}
+
 int close(int fd) {
   int rc = android_fdsan_close_with_tag(fd, 0);
   if (rc == -1 && errno == EINTR) {
diff --git a/libc/include/android/fdsan.h b/libc/include/android/fdsan.h
index 1169ed0..83b9318 100644
--- a/libc/include/android/fdsan.h
+++ b/libc/include/android/fdsan.h
@@ -197,4 +197,8 @@
  */
 enum android_fdsan_error_level android_fdsan_set_error_level(enum android_fdsan_error_level new_level) __INTRODUCED_IN(29) __attribute__((__weak__));
 
+/*
+ * Set the error level to the global setting if available, or a default value.
+ */
+enum android_fdsan_error_level android_fdsan_set_error_level_from_property(enum android_fdsan_error_level default_level) __INTRODUCED_IN(30) __attribute__((__weak__));
 __END_DECLS
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index dceb116..689b650 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -361,3 +361,6 @@
 
 #include <android/versioning.h>
 #include <android/api-level.h>
+#if __has_include(<android/ndk-version.h>)
+#include <android/ndk-version.h>
+#endif
diff --git a/libc/malloc_debug/Android.bp b/libc/malloc_debug/Android.bp
index d6b8531..2bff260 100644
--- a/libc/malloc_debug/Android.bp
+++ b/libc/malloc_debug/Android.bp
@@ -27,6 +27,12 @@
     },
     native_coverage: false,
 
+    target: {
+        android: {
+            static_libs: ["libc++demangle"],
+        },
+    },
+
     // -Wno-error=format-zero-length needed for gcc to compile.
     cflags: [
         "-Wall",
diff --git a/linker/Android.bp b/linker/Android.bp
index bdb7c17..e2cdd14 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -295,7 +295,10 @@
 
     target: {
         android: {
-            static_libs: ["libdebuggerd_handler_fallback"],
+            static_libs: [
+                "libc++demangle",
+                "libdebuggerd_handler_fallback",
+            ],
         },
     },
     compile_multilib: "both",
diff --git a/linker/linker_config.cpp b/linker/linker_config.cpp
index 46c91a3..a8c0e36 100644
--- a/linker/linker_config.cpp
+++ b/linker/linker_config.cpp
@@ -408,9 +408,6 @@
       params.push_back({ "SDK_VER", buf });
     }
 
-    static std::string vndk = Config::get_vndk_version_string('-');
-    params.push_back({ "VNDK_VER", vndk });
-
     for (auto& path : paths) {
       format_string(&path, params);
     }
diff --git a/linker/linker_sdk_versions.cpp b/linker/linker_sdk_versions.cpp
index b06f3e6..29c0f4a 100644
--- a/linker/linker_sdk_versions.cpp
+++ b/linker/linker_sdk_versions.cpp
@@ -26,10 +26,13 @@
  * SUCH DAMAGE.
  */
 
-#include "linker.h"
-#include <android/api-level.h>
 #include <atomic>
 
+#include <android/api-level.h>
+#include <android/fdsan.h>
+
+#include "linker.h"
+
 static std::atomic<int> g_target_sdk_version(__ANDROID_API__);
 
 void set_application_target_sdk_version(int target) {
@@ -38,6 +41,10 @@
     target = __ANDROID_API__;
   }
   g_target_sdk_version = target;
+
+  if (target < 30) {
+    android_fdsan_set_error_level_from_property(ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE);
+  }
 }
 
 int get_application_target_sdk_version() {
diff --git a/tests/Android.bp b/tests/Android.bp
index 42d280b..4477b52 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -286,6 +286,7 @@
         "-Wno-builtin-memcpy-chk-size",
         "-Wno-format-security",
         "-Wno-format-zero-length",
+        "-Wno-fortify-source",
         "-Wno-memset-transposed-args",
         "-Wno-strlcpy-strlcat-size",
         "-Wno-strncat-size",
diff --git a/tests/clang_fortify_tests.cpp b/tests/clang_fortify_tests.cpp
index 1b6b898..6923302 100644
--- a/tests/clang_fortify_tests.cpp
+++ b/tests/clang_fortify_tests.cpp
@@ -36,6 +36,11 @@
 // Similarly, there are a few overload tricks we have to emit errors. Ignore any notes from those.
 // expected-note@* 0+{{candidate function}}
 
+// FIXME(b/138701943): Silence warnings produced by -Wfortify-source since they're expected.
+// expected-warning@* 0+{{will always overflow}}
+// expected-warning@* 0+{{size argument is too large}}
+// expected-note@* 0+{{has been explicitly marked unavailable here}}
+
 #ifndef _FORTIFY_SOURCE
 #error "_FORTIFY_SOURCE must be defined"
 #endif
diff --git a/tests/libs/segment_gap_outer.lds b/tests/libs/segment_gap_outer.lds
index c2961b2..0f175af 100644
--- a/tests/libs/segment_gap_outer.lds
+++ b/tests/libs/segment_gap_outer.lds
@@ -1,15 +1,14 @@
 SECTIONS {
-  # This starts off fairly normal: rodata, text, data, relro, bss with
+  # This starts off fairly normal: rodata, text, dynamic, data, bss with
   # appropriate alignment between them.
   . = SIZEOF_HEADERS;
   .rodata : {}
   . = ALIGN(0x1000);
   .text : {}
   . = ALIGN(0x1000);
+  .dynamic : {}
+  . = ALIGN(0x1000);
   .data : {}
-  . = ALIGN(0x1000);
-  .data.rel.ro : {}
-  . = ALIGN(0x1000);
   .bss : {}
 
   # Now create the gap. We need a text segment first to prevent the linker from
diff --git a/tests/stdatomic_test.cpp b/tests/stdatomic_test.cpp
index a9665d1..9911d64 100644
--- a/tests/stdatomic_test.cpp
+++ b/tests/stdatomic_test.cpp
@@ -16,12 +16,9 @@
 
 #include <gtest/gtest.h>
 
-#if defined(__ANDROID__)
+// The real <stdatomic.h> checks for the availability of C++'s atomics and uses them if present. Since
+// we want to test the libc versions, we instead include <bits/stdatomic.h> where they're actually defined.
 #include <bits/stdatomic.h>
-#else
-#undef _USING_LIBCXX  //TODO(b/137876753): Remove this
-#include <stdatomic.h>
-#endif
 
 #include <pthread.h>
 #include <stdint.h>