Merge changes from topic "revert-2803156-loader_crt_pad_segment-HJBTSCOMQA" into main

* changes:
  Revert "bionic: loader: Extend LOAD segment VMAs"
  Revert "bionic: loader: Extend GNU_RELRO protection"
diff --git a/android-changes-for-ndk-developers.md b/android-changes-for-ndk-developers.md
index ef5d34d..26e57b6 100644
--- a/android-changes-for-ndk-developers.md
+++ b/android-changes-for-ndk-developers.md
@@ -227,7 +227,7 @@
 information using widely-available tools.)
 
 ```
-$ readelf --header libBroken.so | grep 'section headers'
+$ readelf --headers libBroken.so | grep 'section headers'
   Start of section headers:          0 (bytes into file)
   Size of section headers:           0 (bytes)
   Number of section headers:         0
diff --git a/benchmarks/atomic_benchmark.cpp b/benchmarks/atomic_benchmark.cpp
index 487b71c..e3a6fb2 100644
--- a/benchmarks/atomic_benchmark.cpp
+++ b/benchmarks/atomic_benchmark.cpp
@@ -37,11 +37,9 @@
 // We assume that the compiler is not smart enough to optimize away fences in a single-threaded
 // program. If that changes, we'll need to add a second thread.
 
-// We're going to use `++` on this volatile in all the tests. This is
-// fine, because we're only using `volatile` in the "don't optimize this out"
-// sense, and don't care whether the increment is atomic or not.
-#pragma clang diagnostic ignored "-Wdeprecated-volatile"
+// We increment the counter this way to avoid -Wdeprecated-volatile warnings.
 static volatile unsigned counter;
+#define INC_COUNTER() counter = counter + 1
 
 std::atomic<int> test_loc(0);
 
@@ -51,7 +49,7 @@
 
 void BM_atomic_empty(benchmark::State& state) {
   while (state.KeepRunning()) {
-    ++counter;
+    INC_COUNTER();
   }
 }
 BIONIC_BENCHMARK(BM_atomic_empty);
@@ -60,7 +58,7 @@
   unsigned result = 0;
   while (state.KeepRunning()) {
     result += test_loc.load(std::memory_order_relaxed);
-    ++counter;
+    INC_COUNTER();
   }
   sink = result;
 }
@@ -70,7 +68,7 @@
   unsigned result = 0;
   while (state.KeepRunning()) {
     result += test_loc.load(std::memory_order_acquire);
-    ++counter;
+    INC_COUNTER();
   }
   sink = result;
 }
@@ -80,7 +78,7 @@
   int i = counter;
   while (state.KeepRunning()) {
     test_loc.store(++i, std::memory_order_release);
-    ++counter;
+    INC_COUNTER();
   }
 }
 BIONIC_BENCHMARK(BM_atomic_store_release);
@@ -89,7 +87,7 @@
   int i = counter;
   while (state.KeepRunning()) {
     test_loc.store(++i, std::memory_order_seq_cst);
-    ++counter;
+    INC_COUNTER();
   }
 }
 BIONIC_BENCHMARK(BM_atomic_store_seq_cst);
@@ -98,7 +96,7 @@
   unsigned result = 0;
   while (state.KeepRunning()) {
     result += test_loc.fetch_add(1, std::memory_order_relaxed);
-    ++counter;
+    INC_COUNTER();
   }
   sink = result;
 }
@@ -108,7 +106,7 @@
   unsigned result = 0;
   while (state.KeepRunning()) {
     result += test_loc.fetch_add(1, std::memory_order_seq_cst);
-    ++counter;
+    INC_COUNTER();
   }
   sink = result;
 }
@@ -122,7 +120,7 @@
   while (state.KeepRunning()) {
     result += test_loc.load(std::memory_order_relaxed);
     std::atomic_thread_fence(std::memory_order_acquire);
-    ++counter;
+    INC_COUNTER();
   }
   sink = result;
 }
@@ -133,7 +131,7 @@
   while (state.KeepRunning()) {
     result += test_loc.load(std::memory_order_relaxed);
     std::atomic_thread_fence(std::memory_order_seq_cst);
-    ++counter;
+    INC_COUNTER();
   }
   sink = result;
 }
@@ -146,7 +144,8 @@
   while (state.KeepRunning()) {
     {
       std::lock_guard<std::mutex> _(mtx);
-      result += ++counter;
+      INC_COUNTER();
+      result += counter;
     }
   }
   sink = result;
diff --git a/docs/32-bit-abi.md b/docs/32-bit-abi.md
index 3be6b1a..7a96e2f 100644
--- a/docs/32-bit-abi.md
+++ b/docs/32-bit-abi.md
@@ -109,3 +109,15 @@
 mutexes for tids that don't fit in 16 bits. This typically manifests as
 a hang in `pthread_mutex_lock` if the libc startup code doesn't detect
 this condition and abort.
+
+
+## `getuid()` and friends wrongly set errno for very large results
+
+This doesn't generally affect Android devices, because we don't have any
+uids/gids/pids large enough, but 32-bit Android doesn't take into account
+that functions like getuid() potentially have return values that cover the
+entire 32-bit, and can't fail. This means that the usual "if the result is
+between -1 and -4096, set errno and return -1" code is inappropriate for
+these functions. Since LP32 is unlikely to be still supported long before
+those limits could ever matter, although -- unlike the others in this
+document -- this defect is actually fixable, it doesn't seem worth fixing.
diff --git a/libc/Android.bp b/libc/Android.bp
index 807073a..e4bedba 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -20,31 +20,6 @@
     ],
 }
 
-libc_common_src_files = [
-    "bionic/ether_aton.c",
-    "bionic/ether_ntoa.c",
-    "bionic/exit.cpp",
-    "bionic/initgroups.c",
-    "bionic/isatty.c",
-    "bionic/sched_cpualloc.c",
-    "bionic/sched_cpucount.c",
-    "bionic/sysprop_helpers.cpp",
-    "stdio/fmemopen.cpp",
-    "stdio/parsefloat.c",
-    "stdio/refill.c",
-    "stdio/stdio.cpp",
-    "stdio/stdio_ext.cpp",
-    "stdio/vfscanf.cpp",
-    "stdio/vfwscanf.cpp",
-]
-
-// off64_t/time64_t support on LP32.
-// ========================================================
-libc_common_src_files_32 = [
-    "bionic/legacy_32_bit_support.cpp",
-    "bionic/time64.c",
-]
-
 libc_common_flags = [
     "-D_LIBC=1",
     "-D__BIONIC_LP32_USE_STAT64",
@@ -491,18 +466,16 @@
 }
 
 // ========================================================
-// libc_openbsd_ndk.a - upstream OpenBSD C library code
-// that can be safely included in the libc_ndk.a (doesn't
-// contain any troublesome global data or constructors).
+// libc_openbsd.a - upstream OpenBSD C library code
 // ========================================================
 //
 // These files are built with the openbsd-compat.h header file
 // automatically included.
-
 cc_library_static {
-    name: "libc_openbsd_ndk",
     defaults: ["libc_defaults"],
     srcs: [
+        "upstream-openbsd/lib/libc/crypt/arc4random.c",
+        "upstream-openbsd/lib/libc/crypt/arc4random_uniform.c",
         "upstream-openbsd/lib/libc/gen/alarm.c",
         "upstream-openbsd/lib/libc/gen/ctype_.c",
         "upstream-openbsd/lib/libc/gen/daemon.c",
@@ -599,62 +572,10 @@
 
         // This file is originally from OpenBSD, and benefits from
         // being compiled with openbsd-compat.h.
+        // TODO: clean this up instead.
         "bionic/fts.c",
     ],
 
-    cflags: [
-        "-Wno-sign-compare",
-        "-Wno-unused-parameter",
-        "-include openbsd-compat.h",
-    ],
-
-    local_include_dirs: [
-        "private",
-        "stdio",
-        "upstream-openbsd/android/include",
-        "upstream-openbsd/lib/libc/include",
-        "upstream-openbsd/lib/libc/gdtoa/",
-    ],
-}
-
-cc_library_static {
-    name: "libc_openbsd_large_stack",
-    defaults: ["libc_defaults"],
-    srcs: [
-        "stdio/vfprintf.cpp",
-        "stdio/vfwprintf.cpp",
-        "upstream-openbsd/lib/libc/string/memmem.c",
-        "upstream-openbsd/lib/libc/string/strstr.c",
-    ],
-    cflags: [
-        "-include openbsd-compat.h",
-        "-Wno-sign-compare",
-        "-Wframe-larger-than=5000",
-    ],
-
-    local_include_dirs: [
-        "private",
-        "upstream-openbsd/android/include/",
-        "upstream-openbsd/lib/libc/include/",
-        "upstream-openbsd/lib/libc/gdtoa/",
-        "upstream-openbsd/lib/libc/stdio/",
-    ],
-}
-
-// ========================================================
-// libc_openbsd.a - upstream OpenBSD C library code
-// ========================================================
-//
-// These files are built with the openbsd-compat.h header file
-// automatically included.
-cc_library_static {
-    defaults: ["libc_defaults"],
-    srcs: [
-        // These two depend on getentropy, which isn't in libc_ndk.a.
-        "upstream-openbsd/lib/libc/crypt/arc4random.c",
-        "upstream-openbsd/lib/libc/crypt/arc4random_uniform.c",
-    ],
-
     // Each architecture has optimized versions of some routines,
     // and only includes the portable C versions of ones it's missing.
     arch: {
@@ -712,11 +633,37 @@
     local_include_dirs: [
         "private",
         "upstream-openbsd/android/include",
+        "stdio",
+        "upstream-openbsd/lib/libc/include",
     ],
 
     name: "libc_openbsd",
 }
 
+cc_library_static {
+    name: "libc_openbsd_large_stack",
+    defaults: ["libc_defaults"],
+    srcs: [
+        "stdio/vfprintf.cpp",
+        "stdio/vfwprintf.cpp",
+        "upstream-openbsd/lib/libc/string/memmem.c",
+        "upstream-openbsd/lib/libc/string/strstr.c",
+    ],
+    cflags: [
+        "-include openbsd-compat.h",
+        "-Wno-sign-compare",
+        "-Wframe-larger-than=5000",
+    ],
+
+    local_include_dirs: [
+        "private",
+        "upstream-openbsd/android/include/",
+        "upstream-openbsd/lib/libc/gdtoa/",
+        "upstream-openbsd/lib/libc/include/",
+        "upstream-openbsd/lib/libc/stdio/",
+    ],
+}
+
 // ========================================================
 // libc_gdtoa.a - upstream OpenBSD C library gdtoa code
 // ========================================================
@@ -833,12 +780,122 @@
 cc_library_static {
     defaults: ["libc_defaults"],
     srcs: [
+        "bionic/NetdClientDispatch.cpp",
+        "bionic/__bionic_get_shell_path.cpp",
+        "bionic/__cmsg_nxthdr.cpp",
+        "bionic/__cxa_thread_atexit_impl.cpp",
+        "bionic/__errno.cpp",
+        "bionic/__gnu_basename.cpp",
+        "bionic/__libc_current_sigrtmax.cpp",
+        "bionic/__libc_current_sigrtmin.cpp",
+        "bionic/abort.cpp",
+        "bionic/accept.cpp",
+        "bionic/access.cpp",
         "bionic/android_set_abort_message.cpp",
         "bionic/android_unsafe_frame_pointer_chase.cpp",
+        "bionic/arpa_inet.cpp",
+        "bionic/assert.cpp",
         "bionic/atexit.cpp",
+        "bionic/atof.cpp",
+        "bionic/bionic_allocator.cpp",
+        "bionic/bionic_arc4random.cpp",
         "bionic/bionic_elf_tls.cpp",
-        "bionic/__cxa_thread_atexit_impl.cpp",
+        "bionic/bionic_futex.cpp",
+        "bionic/bionic_netlink.cpp",
+        "bionic/bionic_systrace.cpp",
+        "bionic/bionic_time_conversions.cpp",
+        "bionic/brk.cpp",
+        "bionic/c16rtomb.cpp",
+        "bionic/c32rtomb.cpp",
+        "bionic/chmod.cpp",
+        "bionic/chown.cpp",
+        "bionic/clearenv.cpp",
+        "bionic/clock.cpp",
+        "bionic/clock_getcpuclockid.cpp",
+        "bionic/clock_nanosleep.cpp",
+        "bionic/clone.cpp",
+        "bionic/ctype.cpp",
+        "bionic/dirent.cpp",
+        "bionic/dup.cpp",
+        "bionic/environ.cpp",
+        "bionic/error.cpp",
+        "bionic/ether_aton.c",
+        "bionic/ether_ntoa.c",
+        "bionic/eventfd.cpp",
+        "bionic/exec.cpp",
+        "bionic/execinfo.cpp",
+        "bionic/exit.cpp",
+        "bionic/faccessat.cpp",
+        "bionic/fchmod.cpp",
+        "bionic/fchmodat.cpp",
+        "bionic/fcntl.cpp",
+        "bionic/fdsan.cpp",
+        "bionic/fdtrack.cpp",
+        "bionic/ffs.cpp",
+        "bionic/fgetxattr.cpp",
+        "bionic/flistxattr.cpp",
         "bionic/fork.cpp",
+        "bionic/fpclassify.cpp",
+        "bionic/fsetxattr.cpp",
+        "bionic/ftruncate.cpp",
+        "bionic/ftw.cpp",
+        "bionic/futimens.cpp",
+        "bionic/getcwd.cpp",
+        "bionic/getdomainname.cpp",
+        "bionic/getentropy.cpp",
+        "bionic/gethostname.cpp",
+        "bionic/getloadavg.cpp",
+        "bionic/getpagesize.cpp",
+        "bionic/getpgrp.cpp",
+        "bionic/getpid.cpp",
+        "bionic/getpriority.cpp",
+        "bionic/gettid.cpp",
+        "bionic/get_device_api_level.cpp",
+        "bionic/grp_pwd.cpp",
+        "bionic/grp_pwd_file.cpp",
+        "bionic/heap_zero_init.cpp",
+        "bionic/iconv.cpp",
+        "bionic/icu_wrappers.cpp",
+        "bionic/ifaddrs.cpp",
+        "bionic/initgroups.c",
+        "bionic/inotify_init.cpp",
+        "bionic/ioctl.cpp",
+        "bionic/isatty.c",
+        "bionic/killpg.cpp",
+        "bionic/langinfo.cpp",
+        "bionic/lchown.cpp",
+        "bionic/lfs64_support.cpp",
+        "bionic/libc_init_common.cpp",
+        "bionic/libgen.cpp",
+        "bionic/link.cpp",
+        "bionic/locale.cpp",
+        "bionic/lockf.cpp",
+        "bionic/lstat.cpp",
+        "bionic/mblen.cpp",
+        "bionic/mbrtoc16.cpp",
+        "bionic/mbrtoc32.cpp",
+        "bionic/mempcpy.cpp",
+        "bionic/memset_explicit.cpp",
+        "bionic/mkdir.cpp",
+        "bionic/mkfifo.cpp",
+        "bionic/mknod.cpp",
+        "bionic/mntent.cpp",
+        "bionic/mremap.cpp",
+        "bionic/net_if.cpp",
+        "bionic/netdb.cpp",
+        "bionic/netinet_in.cpp",
+        "bionic/nl_types.cpp",
+        "bionic/open.cpp",
+        "bionic/pathconf.cpp",
+        "bionic/pause.cpp",
+        "bionic/pidfd.cpp",
+        "bionic/pipe.cpp",
+        "bionic/poll.cpp",
+        "bionic/posix_fadvise.cpp",
+        "bionic/posix_fallocate.cpp",
+        "bionic/posix_madvise.cpp",
+        "bionic/posix_timers.cpp",
+        "bionic/preadv_pwritev.cpp",
         "bionic/pthread_atfork.cpp",
         "bionic/pthread_attr.cpp",
         "bionic/pthread_barrier.cpp",
@@ -862,10 +919,95 @@
         "bionic/pthread_setname_np.cpp",
         "bionic/pthread_setschedparam.cpp",
         "bionic/pthread_spinlock.cpp",
+        "bionic/ptrace.cpp",
+        "bionic/pty.cpp",
+        "bionic/raise.cpp",
+        "bionic/rand.cpp",
+        "bionic/readlink.cpp",
+        "bionic/realpath.cpp",
+        "bionic/reboot.cpp",
+        "bionic/recv.cpp",
+        "bionic/recvmsg.cpp",
+        "bionic/rename.cpp",
+        "bionic/rmdir.cpp",
+        "bionic/scandir.cpp",
+        "bionic/sched_cpualloc.c",
+        "bionic/sched_cpucount.c",
+        "bionic/sched_getaffinity.cpp",
+        "bionic/sched_getcpu.cpp",
+        "bionic/semaphore.cpp",
+        "bionic/send.cpp",
+        "bionic/setegid.cpp",
+        "bionic/seteuid.cpp",
         "bionic/setjmp_cookie.cpp",
+        "bionic/setpgrp.cpp",
+        "bionic/sigaction.cpp",
+        "bionic/signal.cpp",
+        "bionic/sigprocmask.cpp",
+        "bionic/sleep.cpp",
+        "bionic/socketpair.cpp",
+        "bionic/spawn.cpp",
+        "bionic/stat.cpp",
+        "bionic/stdlib_l.cpp",
+        "bionic/strerror.cpp",
+        "bionic/string_l.cpp",
+        "bionic/strings_l.cpp",
+        "bionic/strsignal.cpp",
+        "bionic/strtol.cpp",
+        "bionic/strtold.cpp",
+        "bionic/swab.cpp",
+        "bionic/symlink.cpp",
+        "bionic/sync_file_range.cpp",
         "bionic/sysconf.cpp",
+        "bionic/sys_epoll.cpp",
+        "bionic/sys_msg.cpp",
+        "bionic/sys_sem.cpp",
+        "bionic/sys_shm.cpp",
+        "bionic/sys_signalfd.cpp",
+        "bionic/sys_statfs.cpp",
+        "bionic/sys_statvfs.cpp",
         "bionic/sys_thread_properties.cpp",
+        "bionic/sys_time.cpp",
+        "bionic/sysinfo.cpp",
+        "bionic/syslog.cpp",
+        "bionic/sysprop_helpers.cpp",
+        "bionic/system.cpp",
+        "bionic/system_property_api.cpp",
+        "bionic/system_property_set.cpp",
+        "bionic/tdestroy.cpp",
+        "bionic/termios.cpp",
+        "bionic/thread_private.cpp",
+        "bionic/threads.cpp",
+        "bionic/time.cpp",
+        "bionic/time_l.cpp",
+        "bionic/tmpfile.cpp",
+        "bionic/umount.cpp",
+        "bionic/unlink.cpp",
+        "bionic/usleep.cpp",
+        "bionic/utmp.cpp",
         "bionic/vdso.cpp",
+        "bionic/wait.cpp",
+        "bionic/wchar.cpp",
+        "bionic/wchar_l.cpp",
+        "bionic/wcstod.cpp",
+        "bionic/wctype.cpp",
+        "bionic/wcwidth.cpp",
+        "bionic/wmempcpy.cpp",
+
+        // Forked but not yet cleaned up/rewritten stdio code.
+        // TODO: finish cleanup.
+        "stdio/fmemopen.cpp",
+        "stdio/parsefloat.c",
+        "stdio/refill.c",
+        "stdio/stdio.cpp",
+        "stdio/stdio_ext.cpp",
+        "stdio/vfscanf.cpp",
+        "stdio/vfwscanf.cpp",
+
+        // TODO: why isn't this in a static-libc-only module?
+        // This contains a weak stub implementation of __find_icu_symbol for wctype.cpp,
+        // which will be overridden by the actual one in libc.so.
+        "bionic/icu_static.cpp",
     ],
 
     arch: {
@@ -1074,6 +1216,26 @@
         },
     },
 
+    multilib: {
+        lib32: {
+            srcs: [
+                // off64_t/time64_t support on LP32.
+                "bionic/legacy_32_bit_support.cpp",
+                "bionic/time64.c",
+
+                // TODO: move to libc/bionic/legacy_32_bit_support.cpp or #if __LP64__ instead.
+                "bionic/mmap.cpp",
+            ],
+        },
+    },
+
+    local_include_dirs: ["stdio"],
+    generated_headers: ["generated_android_ids"],
+
+    whole_static_libs: [
+        "libsystemproperties",
+    ],
+
     cppflags: ["-Wold-style-cast"],
     include_dirs: ["bionic/libstdc++/include"],
     name: "libc_bionic",
@@ -1088,208 +1250,6 @@
 }
 
 // ========================================================
-// libc_bionic_ndk.a- The portions of libc_bionic that can
-// be safely used in libc_ndk.a (no troublesome global data
-// or constructors).
-// ========================================================
-cc_library_static {
-    defaults: ["libc_defaults"],
-    srcs: [
-        "bionic/NetdClientDispatch.cpp",
-        "bionic/__bionic_get_shell_path.cpp",
-        "bionic/__cmsg_nxthdr.cpp",
-        "bionic/__errno.cpp",
-        "bionic/__gnu_basename.cpp",
-        "bionic/__libc_current_sigrtmax.cpp",
-        "bionic/__libc_current_sigrtmin.cpp",
-        "bionic/abort.cpp",
-        "bionic/accept.cpp",
-        "bionic/access.cpp",
-        "bionic/arpa_inet.cpp",
-        "bionic/assert.cpp",
-        "bionic/atof.cpp",
-        "bionic/bionic_allocator.cpp",
-        "bionic/bionic_arc4random.cpp",
-        "bionic/bionic_futex.cpp",
-        "bionic/bionic_netlink.cpp",
-        "bionic/bionic_systrace.cpp",
-        "bionic/bionic_time_conversions.cpp",
-        "bionic/brk.cpp",
-        "bionic/c16rtomb.cpp",
-        "bionic/c32rtomb.cpp",
-        "bionic/chmod.cpp",
-        "bionic/chown.cpp",
-        "bionic/clearenv.cpp",
-        "bionic/clock.cpp",
-        "bionic/clock_getcpuclockid.cpp",
-        "bionic/clock_nanosleep.cpp",
-        "bionic/clone.cpp",
-        "bionic/ctype.cpp",
-        "bionic/dirent.cpp",
-        "bionic/dup.cpp",
-        "bionic/environ.cpp",
-        "bionic/error.cpp",
-        "bionic/eventfd.cpp",
-        "bionic/exec.cpp",
-        "bionic/execinfo.cpp",
-        "bionic/faccessat.cpp",
-        "bionic/fchmod.cpp",
-        "bionic/fchmodat.cpp",
-        "bionic/fcntl.cpp",
-        "bionic/fdsan.cpp",
-        "bionic/fdtrack.cpp",
-        "bionic/ffs.cpp",
-        "bionic/fgetxattr.cpp",
-        "bionic/flistxattr.cpp",
-        "bionic/fpclassify.cpp",
-        "bionic/fsetxattr.cpp",
-        "bionic/ftruncate.cpp",
-        "bionic/ftw.cpp",
-        "bionic/futimens.cpp",
-        "bionic/getcwd.cpp",
-        "bionic/getdomainname.cpp",
-        "bionic/getentropy.cpp",
-        "bionic/gethostname.cpp",
-        "bionic/getloadavg.cpp",
-        "bionic/getpagesize.cpp",
-        "bionic/getpgrp.cpp",
-        "bionic/getpid.cpp",
-        "bionic/getpriority.cpp",
-        "bionic/gettid.cpp",
-        "bionic/get_device_api_level.cpp",
-        "bionic/grp_pwd.cpp",
-        "bionic/grp_pwd_file.cpp",
-        "bionic/heap_zero_init.cpp",
-        "bionic/iconv.cpp",
-        "bionic/icu_wrappers.cpp",
-        "bionic/ifaddrs.cpp",
-        "bionic/inotify_init.cpp",
-        "bionic/ioctl.cpp",
-        "bionic/killpg.cpp",
-        "bionic/langinfo.cpp",
-        "bionic/lchown.cpp",
-        "bionic/lfs64_support.cpp",
-        "bionic/libc_init_common.cpp",
-        "bionic/libgen.cpp",
-        "bionic/link.cpp",
-        "bionic/locale.cpp",
-        "bionic/lockf.cpp",
-        "bionic/lstat.cpp",
-        "bionic/mblen.cpp",
-        "bionic/mbrtoc16.cpp",
-        "bionic/mbrtoc32.cpp",
-        "bionic/mempcpy.cpp",
-        "bionic/memset_explicit.cpp",
-        "bionic/mkdir.cpp",
-        "bionic/mkfifo.cpp",
-        "bionic/mknod.cpp",
-        "bionic/mntent.cpp",
-        "bionic/mremap.cpp",
-        "bionic/net_if.cpp",
-        "bionic/netdb.cpp",
-        "bionic/netinet_in.cpp",
-        "bionic/nl_types.cpp",
-        "bionic/open.cpp",
-        "bionic/pathconf.cpp",
-        "bionic/pause.cpp",
-        "bionic/pidfd.cpp",
-        "bionic/pipe.cpp",
-        "bionic/poll.cpp",
-        "bionic/posix_fadvise.cpp",
-        "bionic/posix_fallocate.cpp",
-        "bionic/posix_madvise.cpp",
-        "bionic/posix_timers.cpp",
-        "bionic/preadv_pwritev.cpp",
-        "bionic/ptrace.cpp",
-        "bionic/pty.cpp",
-        "bionic/raise.cpp",
-        "bionic/rand.cpp",
-        "bionic/readlink.cpp",
-        "bionic/realpath.cpp",
-        "bionic/reboot.cpp",
-        "bionic/recv.cpp",
-        "bionic/recvmsg.cpp",
-        "bionic/rename.cpp",
-        "bionic/rmdir.cpp",
-        "bionic/scandir.cpp",
-        "bionic/sched_getaffinity.cpp",
-        "bionic/sched_getcpu.cpp",
-        "bionic/semaphore.cpp",
-        "bionic/send.cpp",
-        "bionic/setegid.cpp",
-        "bionic/seteuid.cpp",
-        "bionic/setpgrp.cpp",
-        "bionic/sigaction.cpp",
-        "bionic/signal.cpp",
-        "bionic/sigprocmask.cpp",
-        "bionic/sleep.cpp",
-        "bionic/socketpair.cpp",
-        "bionic/spawn.cpp",
-        "bionic/stat.cpp",
-        "bionic/stdlib_l.cpp",
-        "bionic/strerror.cpp",
-        "bionic/string_l.cpp",
-        "bionic/strings_l.cpp",
-        "bionic/strsignal.cpp",
-        "bionic/strtol.cpp",
-        "bionic/strtold.cpp",
-        "bionic/swab.cpp",
-        "bionic/symlink.cpp",
-        "bionic/sync_file_range.cpp",
-        "bionic/sys_epoll.cpp",
-        "bionic/sys_msg.cpp",
-        "bionic/sys_sem.cpp",
-        "bionic/sys_shm.cpp",
-        "bionic/sys_signalfd.cpp",
-        "bionic/sys_statfs.cpp",
-        "bionic/sys_statvfs.cpp",
-        "bionic/sys_time.cpp",
-        "bionic/sysinfo.cpp",
-        "bionic/syslog.cpp",
-        "bionic/system.cpp",
-        "bionic/system_property_api.cpp",
-        "bionic/system_property_set.cpp",
-        "bionic/tdestroy.cpp",
-        "bionic/termios.cpp",
-        "bionic/thread_private.cpp",
-        "bionic/threads.cpp",
-        "bionic/time.cpp",
-        "bionic/time_l.cpp",
-        "bionic/tmpfile.cpp",
-        "bionic/umount.cpp",
-        "bionic/unlink.cpp",
-        "bionic/usleep.cpp",
-        "bionic/utmp.cpp",
-        "bionic/wait.cpp",
-        "bionic/wchar.cpp",
-        "bionic/wchar_l.cpp",
-        "bionic/wcstod.cpp",
-        "bionic/wctype.cpp",
-        "bionic/wcwidth.cpp",
-        "bionic/wmempcpy.cpp",
-
-        // This contains a weak stub implementation of __find_icu_symbol for wctype.cpp,
-        // which will be overridden by the actual one in libc.so.
-        "bionic/icu_static.cpp",
-    ],
-
-    multilib: {
-        lib32: {
-            // LP32 cruft
-            srcs: ["bionic/mmap.cpp"],
-        },
-    },
-    whole_static_libs: [
-        "libsystemproperties",
-    ],
-    cppflags: ["-Wold-style-cast"],
-    local_include_dirs: ["stdio"],
-    include_dirs: ["bionic/libstdc++/include"],
-    name: "libc_bionic_ndk",
-    generated_headers: ["generated_android_ids"],
-}
-
-// ========================================================
 // libc_syscalls.a
 // ========================================================
 
@@ -1375,25 +1335,17 @@
 }
 
 // ========================================================
-// libc_common.a
+// libc_common.a --- everything shared by libc.a and libc.so
 // ========================================================
 
 cc_library_static {
     defaults: ["libc_defaults"],
     name: "libc_common",
 
-    srcs: libc_common_src_files,
-    multilib: {
-        lib32: {
-            srcs: libc_common_src_files_32,
-        },
-    },
-
     whole_static_libs: [
         "libarm-optimized-routines-string",
         "libasync_safe",
         "libc_bionic",
-        "libc_bionic_ndk",
         "libc_bootstrap",
         "libc_dns",
         "libc_fortify",
@@ -1404,7 +1356,6 @@
         "libc_netbsd",
         "libc_openbsd",
         "libc_openbsd_large_stack",
-        "libc_openbsd_ndk",
         "libc_syscalls",
         "libc_tzcode",
         "libstdc++",
@@ -1418,7 +1369,7 @@
 }
 
 // ========================================================
-// libc_static_dispatch.a
+// libc_static_dispatch.a --- libc.a ifuncs
 // ========================================================
 cc_library_static {
     defaults: ["libc_defaults"],
@@ -1444,7 +1395,7 @@
 }
 
 // ========================================================
-// libc_dynamic_dispatch.a
+// libc_dynamic_dispatch.a --- libc.so ifuncs
 // ========================================================
 cc_library_static {
     defaults: ["libc_defaults"],
@@ -1938,6 +1889,7 @@
         "//external/gwp_asan",
         "//external/jemalloc_new",
         "//external/libunwind_llvm",
+        "//external/llvm-libc",
         "//external/scudo",
         "//system/core/property_service/libpropertyinfoparser",
         "//system/extras/toolchain-extras",
diff --git a/libc/private/bsd_sys_param.h b/libc/private/bsd_sys_param.h
index be5f692..ab54aa0 100644
--- a/libc/private/bsd_sys_param.h
+++ b/libc/private/bsd_sys_param.h
@@ -20,4 +20,4 @@
 
 /* OpenBSD has these in <sys/param.h>, but "ALIGN" isn't something we want to reserve. */
 #define ALIGNBYTES (sizeof(uintptr_t) - 1)
-#define ALIGN(p) (((uintptr_t)(p) + ALIGNBYTES) & ~ALIGNBYTES)
+#define ALIGN(p) ((__BIONIC_CAST(reinterpret_cast, uintptr_t, p) + ALIGNBYTES) & ~ALIGNBYTES)
diff --git a/libc/stdio/local.h b/libc/stdio/local.h
index a5eb636..62efea1 100644
--- a/libc/stdio/local.h
+++ b/libc/stdio/local.h
@@ -236,7 +236,7 @@
 /* OpenBSD exposes these in <stdio.h>, but we only want them exposed to the implementation. */
 #define __sferror(p) (((p)->_flags & __SERR) != 0)
 #define __sclearerr(p) ((void)((p)->_flags &= ~(__SERR | __SEOF)))
-#define __sgetc(p) (--(p)->_r < 0 ? __srget(p) : (int)(*(p)->_p++))
+#define __sgetc(p) (--(p)->_r < 0 ? __srget(p) : __BIONIC_CAST(static_cast, int, *(p)->_p++))
 
 /* OpenBSD declares these in fvwrite.h, but we share them with C++ parts of the implementation. */
 struct __siov {
@@ -288,7 +288,7 @@
 char* __hldtoa(long double, const char*, int, int*, int*, char**);
 char* __ldtoa(long double*, int, int, int*, int*, char**);
 
-#define WCIO_GET(fp) (_EXT(fp) ? &(_EXT(fp)->_wcio) : (struct wchar_io_data*)0)
+#define WCIO_GET(fp) (_EXT(fp) ? &(_EXT(fp)->_wcio) : NULL)
 
 #define ORIENT_BYTES (-1)
 #define ORIENT_UNKNOWN 0
diff --git a/libc/stdio/scanf_common.h b/libc/stdio/scanf_common.h
index 8132e90..1b6b87f 100644
--- a/libc/stdio/scanf_common.h
+++ b/libc/stdio/scanf_common.h
@@ -82,7 +82,7 @@
 #define CT_FLOAT 4   // Float: strtod
 
 #define to_digit(c) static_cast<int>((c) - '0')
-#define is_digit(c) ((unsigned)to_digit(c) <= 9)
+#define is_digit(c) (static_cast<unsigned>(to_digit(c)) <= 9)
 
 // Append a digit to a value and check for overflow.
 #define APPEND_DIGIT(val, dig)               \
@@ -112,4 +112,4 @@
   __fortify_fatal("%%w%s%d is unsupported", fast ? "f" : "", size);
 }
 
-#pragma clang diagnostic pop
\ No newline at end of file
+#pragma clang diagnostic pop
diff --git a/libc/stdio/vfscanf.cpp b/libc/stdio/vfscanf.cpp
index 3607995..92ff541 100644
--- a/libc/stdio/vfscanf.cpp
+++ b/libc/stdio/vfscanf.cpp
@@ -629,10 +629,10 @@
          * as `[-+]0`.
          */
         if (flags & NDIGITS) {
-          if (p > buf) (void)ungetc(*(u_char*)--p, fp);
+          if (p > buf) ungetc(*reinterpret_cast<u_char*>(--p), fp);
           goto match_failure;
         }
-        c = ((u_char*)p)[-1];
+        c = reinterpret_cast<u_char*>(p)[-1];
         if ((base == 2 && (c == 'b' || c == 'B')) || c == 'x' || c == 'X') {
           --p;
           (void)ungetc(c, fp);
@@ -647,7 +647,7 @@
             res = strtoimax(buf, nullptr, base);
           }
           if (flags & POINTER) {
-            *va_arg(ap, void**) = (void*)(uintptr_t)res;
+            *va_arg(ap, void**) = reinterpret_cast<void*>(res);
           } else if (flags & MAXINT) {
             *va_arg(ap, intmax_t*) = res;
           } else if (flags & LLONG) {
@@ -685,7 +685,7 @@
             float res = strtof(buf, &p);
             *va_arg(ap, float*) = res;
           }
-          if ((size_t)(p - buf) != width) abort();
+          if (static_cast<size_t>(p - buf) != width) abort();
           nassigned++;
         }
         nread += width;
diff --git a/libc/stdio/vfwscanf.cpp b/libc/stdio/vfwscanf.cpp
index 3df4a87..21d1783 100644
--- a/libc/stdio/vfwscanf.cpp
+++ b/libc/stdio/vfwscanf.cpp
@@ -32,6 +32,7 @@
  */
 
 #include "scanf_common.h"
+
 // An interpretive version of __sccl from vfscanf.c --- a table of all wchar_t values would
 // be a little too expensive, and some kind of compressed version isn't worth the trouble.
 static inline bool in_ccl(wchar_t wc, const wchar_t* ccl) {
@@ -335,7 +336,7 @@
           if (!(flags & SUPPRESS)) p = va_arg(ap, wchar_t*);
           n = 0;
           while (width-- != 0 && (wi = __fgetwc_unlock(fp)) != WEOF) {
-            if (!(flags & SUPPRESS)) *p++ = (wchar_t)wi;
+            if (!(flags & SUPPRESS)) *p++ = static_cast<wchar_t>(wi);
             n++;
           }
           if (n == 0) goto input_failure;
@@ -348,10 +349,10 @@
           while (width != 0 && (wi = __fgetwc_unlock(fp)) != WEOF) {
             if (width >= MB_CUR_MAX && !(flags & SUPPRESS)) {
               nconv = wcrtomb(mbp, wi, &mbs);
-              if (nconv == (size_t)-1) goto input_failure;
+              if (nconv == static_cast<size_t>(-1)) goto input_failure;
             } else {
               nconv = wcrtomb(mbbuf, wi, &mbs);
-              if (nconv == (size_t)-1) goto input_failure;
+              if (nconv == static_cast<size_t>(-1)) goto input_failure;
               if (nconv > width) {
                 __ungetwc(wi, fp);
                 break;
@@ -373,7 +374,7 @@
       case CT_STRING:
         // CT_CCL: scan a (nonempty) character class (sets NOSKIP).
         // CT_STRING: like CCL, but zero-length string OK, & no NOSKIP.
-        if (width == 0) width = (size_t)~0; // 'infinity'.
+        if (width == 0) width = SIZE_MAX; // 'infinity'.
         if ((flags & SUPPRESS) && (flags & LONG)) {
           n = 0;
           while ((wi = __fgetwc_unlock(fp)) != WEOF && width-- != 0 && ((c == CT_CCL && in_ccl(wi, ccl)) || (c == CT_STRING && !iswspace(wi)))) n++;
@@ -381,7 +382,7 @@
         } else if (flags & LONG) {
           p0 = p = va_arg(ap, wchar_t*);
           while ((wi = __fgetwc_unlock(fp)) != WEOF && width-- != 0 && ((c == CT_CCL && in_ccl(wi, ccl)) || (c == CT_STRING && !iswspace(wi)))) {
-            *p++ = (wchar_t)wi;
+            *p++ = static_cast<wchar_t>(wi);
           }
           if (wi != WEOF) __ungetwc(wi, fp);
           n = p - p0;
@@ -392,10 +393,10 @@
           while ((wi = __fgetwc_unlock(fp)) != WEOF && width != 0 && ((c == CT_CCL && in_ccl(wi, ccl)) || (c == CT_STRING && !iswspace(wi)))) {
             if (width >= MB_CUR_MAX && !(flags & SUPPRESS)) {
               nconv = wcrtomb(mbp, wi, &mbs);
-              if (nconv == (size_t)-1) goto input_failure;
+              if (nconv == static_cast<size_t>(-1)) goto input_failure;
             } else {
               nconv = wcrtomb(mbbuf, wi, &mbs);
-              if (nconv == (size_t)-1) goto input_failure;
+              if (nconv == static_cast<size_t>(-1)) goto input_failure;
               if (nconv > width) break;
               if (!(flags & SUPPRESS)) memcpy(mbp, mbbuf, nconv);
             }
@@ -485,7 +486,7 @@
             case 'e':
             case 'f':
               if (base == 0) base = 10;
-              if (base != 16 && (int)(c - '0') >= base) break; /* not legal here */
+              if (base != 16 && static_cast<int>(c - '0') >= base) break; /* not legal here */
               flags &= ~(SIGNOK | PFBOK | PFXOK | NDIGITS);
               goto ok;
 
@@ -523,7 +524,7 @@
           /*
            * c is legal: store it and look at the next.
            */
-          *p++ = (wchar_t)c;
+          *p++ = static_cast<wchar_t>(c);
         }
         /*
          * If we had only a sign, it is no good; push back the sign.
@@ -548,7 +549,7 @@
           else
             res = wcstoumax(buf, NULL, base);
           if (flags & POINTER)
-            *va_arg(ap, void**) = (void*)(uintptr_t)res;
+            *va_arg(ap, void**) = reinterpret_cast<void*>(res);
           else if (flags & MAXINT)
             *va_arg(ap, intmax_t*) = res;
           else if (flags & LLONG)
@@ -587,7 +588,7 @@
             float res = wcstof(buf, &p);
             *va_arg(ap, float*) = res;
           }
-          if (p - buf != (ptrdiff_t)width) abort();
+          if (static_cast<size_t>(p - buf) != width) abort();
           nassigned++;
         }
         nread += width;
diff --git a/linker/NOTICE b/linker/NOTICE
index 7fd1877..9b66b4e 100644
--- a/linker/NOTICE
+++ b/linker/NOTICE
@@ -390,3 +390,31 @@
 
 -------------------------------------------------------------------
 
+Copyright (C) 2024 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.
+
+-------------------------------------------------------------------
+
diff --git a/linker/linker_phdr.cpp b/linker/linker_phdr.cpp
index 85cd949..60f8868 100644
--- a/linker/linker_phdr.cpp
+++ b/linker/linker_phdr.cpp
@@ -717,11 +717,19 @@
       continue;
     }
 
+    // Some obfuscated ELFs may contain "empty" PT_NOTE program headers that don't
+    // point to any part of the ELF (p_memsz == 0). Skip these since there is
+    // nothing to decode. See: b/324468126
+    if (phdr->p_memsz == 0) {
+      continue;
+    }
+
     // note_fragment is scoped to within the loop so that there is
     // at most 1 PT_NOTE mapped at anytime during this search.
     MappedFileFragment note_fragment;
     if (!note_fragment.Map(fd_, file_offset_, phdr->p_offset, phdr->p_memsz)) {
-      DL_ERR("\"%s\" note mmap failed: %s", name_.c_str(), strerror(errno));
+      DL_ERR("\"%s\": PT_NOTE mmap(nullptr, %zu, PROT_READ, MAP_PRIVATE, %d, %p) failed: %m",
+             name_.c_str(), phdr->p_memsz, fd_, page_start(file_offset_ + phdr->p_offset));
       return false;
     }