Merge "Remove bionic bp2build properties" into main
diff --git a/libc/include/bits/sockaddr_storage.h b/libc/include/bits/sockaddr_storage.h
new file mode 100644
index 0000000..effafab
--- /dev/null
+++ b/libc/include/bits/sockaddr_storage.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+#pragma once
+
+/**
+ * @file bits/sockaddr_storage.h
+ * @brief The `sockaddr_storage` struct.
+ */
+
+#include <sys/cdefs.h>
+
+#include <bits/sa_family_t.h>
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnullability-completeness"
+/**
+ * [sockaddr_storage](https://man7.org/linux/man-pages/man3/sockaddr.3type.html)
+ * is a structure large enough to contain any other `sockaddr_*` type, used to
+ * pass socket addresses without needing to know what kind of socket address
+ * you're passing.
+ */
+struct sockaddr_storage {
+  union {
+    struct {
+      sa_family_t ss_family;
+      char __data[128 - sizeof(sa_family_t)];
+    };
+    void* __align;
+  };
+};
+#pragma clang diagnostic pop
diff --git a/libc/include/netinet/in.h b/libc/include/netinet/in.h
index b235e6e..163e614 100644
--- a/libc/include/netinet/in.h
+++ b/libc/include/netinet/in.h
@@ -33,20 +33,10 @@
 #include <sys/cdefs.h>
 #include <sys/socket.h>
 
-// Include linux/socket.h first to trigger the header guard without
-// the__kernel_sockaddr_storage define, so its definition uses the
-// kernel name.
-#include <linux/socket.h>
-
-// Redefine __kernel_sockaddr_storage to sockaddr_storage so that
-// the structs defined in linux/in.h use the sockaddr_storage defined
-// in sys/sockets.h.
-#define __kernel_sockaddr_storage sockaddr_storage
 #include <linux/in.h>
-#undef __kernel_sockaddr_storage
-
 #include <linux/in6.h>
 #include <linux/ipv6.h>
+#include <linux/socket.h>
 
 __BEGIN_DECLS
 
diff --git a/libc/include/pthread.h b/libc/include/pthread.h
index 9d99aa1..871c62c 100644
--- a/libc/include/pthread.h
+++ b/libc/include/pthread.h
@@ -74,14 +74,9 @@
 #define PTHREAD_BARRIER_SERIAL_THREAD (-1)
 #endif
 
-
 #if defined(__LP64__)
-#if defined(PAGE_SIZE)
 #define PTHREAD_STACK_MIN 16384
 #else
-#define PTHREAD_STACK_MIN 65536
-#endif
-#else
 #define PTHREAD_STACK_MIN 8192
 #endif
 
diff --git a/libc/include/sys/socket.h b/libc/include/sys/socket.h
index 22b88cb..9402e70 100644
--- a/libc/include/sys/socket.h
+++ b/libc/include/sys/socket.h
@@ -39,6 +39,7 @@
 #include <linux/types.h>
 #include <linux/compiler.h>
 
+#include <bits/sockaddr_storage.h>
 #include <bits/sa_family_t.h>
 
 __BEGIN_DECLS
@@ -72,15 +73,6 @@
 
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wnullability-completeness"
-struct sockaddr_storage {
-  union {
-    struct {
-      sa_family_t ss_family;
-      char __data[128 - sizeof(sa_family_t)];
-    };
-    void* __align;
-  };
-};
 
 struct linger {
   int l_onoff;
diff --git a/libc/kernel/tools/cpp.py b/libc/kernel/tools/cpp.py
index 6939bda..08b786a 100755
--- a/libc/kernel/tools/cpp.py
+++ b/libc/kernel/tools/cpp.py
@@ -1247,8 +1247,8 @@
                     # Add an include for the structure to be removed of the form:
                     #  #include <bits/STRUCT_NAME.h>
                     struct_token = b.tokens[i + 1]
-                    if not structs[struct_token.id]:
-                        extra_includes.add("<bits/%s.h>" % struct_token.id)
+                    if struct_token.id in structs and structs[struct_token.id]:
+                        extra_includes.add("<%s>" % structs[struct_token.id])
 
                     # Search forward for the end of the structure.
                     # Very simple search, look for } and ; tokens.
diff --git a/libc/kernel/tools/defaults.py b/libc/kernel/tools/defaults.py
index 9b357f1..1d7b427 100644
--- a/libc/kernel/tools/defaults.py
+++ b/libc/kernel/tools/defaults.py
@@ -28,23 +28,23 @@
     }
 
 # This is the set of known kernel data structures we want to remove from
-# the final headers. If the map value is False, that means that in
-# addition to removing the structure, add an #include <bits/STRUCT.h>
-# to the file.
+# the final headers. If the map value is non-empty, that means that in
+# addition to removing the structure, add a #include to the file.
 kernel_structs_to_remove = {
-    # Remove the structures since they are still the same as
+    # Remove these structures since they are still the same as
     # timeval, itimerval.
-    "__kernel_old_timeval": True,
-    "__kernel_old_itimerval": True,
+    "__kernel_old_timeval": None,
+    "__kernel_old_itimerval": None,
     # Replace all of the below structures with #include <bits/STRUCT.h>
-    "epoll_event": False,
-    "flock": False,
-    "flock64": False,
-    "in_addr": False,
-    "ip_mreq_source": False,
-    "ip_msfilter": False,
-    "tcphdr": False,
-    "timespec": False,
+    "__kernel_sockaddr_storage": "bits/sockaddr_storage.h",
+    "epoll_event": "bits/epoll_event.h",
+    "flock": "bits/flock.h",
+    "flock64": "bits/flock64.h",
+    "in_addr": "bits/in_addr.h",
+    "ip_mreq_source": "bits/ip_mreq_source.h",
+    "ip_msfilter": "bits/ip_msfilter.h",
+    "tcphdr": "bits/tcphdr.h",
+    "timespec": "bits/timespec.h",
     }
 
 # define to true if you want to remove all defined(CONFIG_FOO) tests
@@ -92,6 +92,8 @@
     "__kernel_old_timeval": "timeval",
     # Do the same for __kernel_old_itimerval as for timeval.
     "__kernel_old_itimerval": "itimerval",
+    # Do the same for __kernel_sockaddr_storage.
+    "__kernel_sockaddr_storage": "sockaddr_storage",
     # Replace __packed with __attribute__((__packed__)) to avoid depending
     # on sys/cdefs.h
     "__packed": "__attribute__((__packed__))",
diff --git a/libc/kernel/uapi/linux/in.h b/libc/kernel/uapi/linux/in.h
index e784690..44efdd8 100644
--- a/libc/kernel/uapi/linux/in.h
+++ b/libc/kernel/uapi/linux/in.h
@@ -148,32 +148,32 @@
 #define IP_MSFILTER_SIZE(numsrc) (sizeof(struct ip_msfilter) - sizeof(__u32) + (numsrc) * sizeof(__u32))
 struct group_req {
   __u32 gr_interface;
-  struct __kernel_sockaddr_storage gr_group;
+  struct sockaddr_storage gr_group;
 };
 struct group_source_req {
   __u32 gsr_interface;
-  struct __kernel_sockaddr_storage gsr_group;
-  struct __kernel_sockaddr_storage gsr_source;
+  struct sockaddr_storage gsr_group;
+  struct sockaddr_storage gsr_source;
 };
 struct group_filter {
   union {
     struct {
       __u32 gf_interface_aux;
-      struct __kernel_sockaddr_storage gf_group_aux;
+      struct sockaddr_storage gf_group_aux;
       __u32 gf_fmode_aux;
       __u32 gf_numsrc_aux;
-      struct __kernel_sockaddr_storage gf_slist[1];
+      struct sockaddr_storage gf_slist[1];
     };
     struct {
       __u32 gf_interface;
-      struct __kernel_sockaddr_storage gf_group;
+      struct sockaddr_storage gf_group;
       __u32 gf_fmode;
       __u32 gf_numsrc;
-      struct __kernel_sockaddr_storage gf_slist_flex[];
+      struct sockaddr_storage gf_slist_flex[];
     };
   };
 };
-#define GROUP_FILTER_SIZE(numsrc) (sizeof(struct group_filter) - sizeof(struct __kernel_sockaddr_storage) + (numsrc) * sizeof(struct __kernel_sockaddr_storage))
+#define GROUP_FILTER_SIZE(numsrc) (sizeof(struct group_filter) - sizeof(struct sockaddr_storage) + (numsrc) * sizeof(struct sockaddr_storage))
 #endif
 #if __UAPI_DEF_IN_PKTINFO
 struct in_pktinfo {
diff --git a/libc/kernel/uapi/linux/mptcp.h b/libc/kernel/uapi/linux/mptcp.h
index f00abae..d97f29b 100644
--- a/libc/kernel/uapi/linux/mptcp.h
+++ b/libc/kernel/uapi/linux/mptcp.h
@@ -163,13 +163,13 @@
     struct sockaddr sa_local;
     struct sockaddr_in sin_local;
     struct sockaddr_in6 sin6_local;
-    struct __kernel_sockaddr_storage ss_local;
+    struct sockaddr_storage ss_local;
   };
   union {
     struct sockaddr sa_remote;
     struct sockaddr_in sin_remote;
     struct sockaddr_in6 sin6_remote;
-    struct __kernel_sockaddr_storage ss_remote;
+    struct sockaddr_storage ss_remote;
   };
 };
 struct mptcp_subflow_info {
diff --git a/libc/kernel/uapi/linux/rds.h b/libc/kernel/uapi/linux/rds.h
index bc41946..e2a7a38 100644
--- a/libc/kernel/uapi/linux/rds.h
+++ b/libc/kernel/uapi/linux/rds.h
@@ -205,7 +205,7 @@
   __u64 flags;
 };
 struct rds_get_mr_for_dest_args {
-  struct __kernel_sockaddr_storage dest_addr;
+  struct sockaddr_storage dest_addr;
   struct rds_iovec vec;
   __u64 cookie_addr;
   __u64 flags;
diff --git a/libc/kernel/uapi/linux/socket.h b/libc/kernel/uapi/linux/socket.h
index 936f44a..27890a4 100644
--- a/libc/kernel/uapi/linux/socket.h
+++ b/libc/kernel/uapi/linux/socket.h
@@ -6,17 +6,9 @@
  */
 #ifndef _UAPI_LINUX_SOCKET_H
 #define _UAPI_LINUX_SOCKET_H
+#include <bits/sockaddr_storage.h>
 #define _K_SS_MAXSIZE 128
 typedef unsigned short __kernel_sa_family_t;
-struct __kernel_sockaddr_storage {
-  union {
-    struct {
-      __kernel_sa_family_t ss_family;
-      char __data[_K_SS_MAXSIZE - sizeof(unsigned short)];
-    };
-    void * __align;
-  };
-};
 #define SOCK_SNDBUF_LOCK 1
 #define SOCK_RCVBUF_LOCK 2
 #define SOCK_BUF_LOCK_MASK (SOCK_SNDBUF_LOCK | SOCK_RCVBUF_LOCK)
diff --git a/libc/kernel/uapi/linux/tcp.h b/libc/kernel/uapi/linux/tcp.h
index 20fbcec..65bab54 100644
--- a/libc/kernel/uapi/linux/tcp.h
+++ b/libc/kernel/uapi/linux/tcp.h
@@ -202,7 +202,7 @@
 #define TCP_MD5SIG_FLAG_PREFIX 0x1
 #define TCP_MD5SIG_FLAG_IFINDEX 0x2
 struct tcp_md5sig {
-  struct __kernel_sockaddr_storage tcpm_addr;
+  struct sockaddr_storage tcpm_addr;
   __u8 tcpm_flags;
   __u8 tcpm_prefixlen;
   __u16 tcpm_keylen;
diff --git a/libc/kernel/uapi/rdma/rdma_user_cm.h b/libc/kernel/uapi/rdma/rdma_user_cm.h
index dbe79bc..5228e62 100644
--- a/libc/kernel/uapi/rdma/rdma_user_cm.h
+++ b/libc/kernel/uapi/rdma/rdma_user_cm.h
@@ -76,7 +76,7 @@
   __u32 id;
   __u16 addr_size;
   __u16 reserved;
-  struct __kernel_sockaddr_storage addr;
+  struct sockaddr_storage addr;
 };
 struct rdma_ucm_resolve_ip {
   struct sockaddr_in6 src_addr;
@@ -90,8 +90,8 @@
   __u16 src_size;
   __u16 dst_size;
   __u32 reserved;
-  struct __kernel_sockaddr_storage src_addr;
-  struct __kernel_sockaddr_storage dst_addr;
+  struct sockaddr_storage src_addr;
+  struct sockaddr_storage dst_addr;
 };
 struct rdma_ucm_resolve_route {
   __u32 id;
@@ -125,8 +125,8 @@
   __u16 pkey;
   __u16 src_size;
   __u16 dst_size;
-  struct __kernel_sockaddr_storage src_addr;
-  struct __kernel_sockaddr_storage dst_addr;
+  struct sockaddr_storage src_addr;
+  struct sockaddr_storage dst_addr;
   __u32 ibdev_index;
   __u32 reserved1;
 };
@@ -213,7 +213,7 @@
   __u32 id;
   __u16 addr_size;
   __u16 join_flags;
-  struct __kernel_sockaddr_storage addr;
+  struct sockaddr_storage addr;
 };
 struct rdma_ucm_get_event {
   __aligned_u64 response;
diff --git a/libdl/Android.bp b/libdl/Android.bp
index 762aeef..3bda856 100644
--- a/libdl/Android.bp
+++ b/libdl/Android.bp
@@ -226,10 +226,6 @@
         "//apex_available:platform",
         "com.android.runtime",
     ],
-
-    lto: {
-        never: true,
-    },
 }
 
 ndk_library {
diff --git a/linker/linker_utils_test.cpp b/linker/linker_utils_test.cpp
index 0b881d4..ac98416 100644
--- a/linker/linker_utils_test.cpp
+++ b/linker/linker_utils_test.cpp
@@ -105,15 +105,35 @@
 }
 
 TEST(linker_utils, page_start) {
-  ASSERT_EQ(0x0001000U, page_start(0x0001000));
-  ASSERT_EQ(0x3002000U, page_start(0x300222f));
-  ASSERT_EQ(0x6001000U, page_start(0x6001fff));
+  const size_t kPageSize = page_size();
+
+  if (kPageSize == 4096) {
+    ASSERT_EQ(0x0001000U, page_start(0x0001000));
+    ASSERT_EQ(0x3002000U, page_start(0x300222f));
+    ASSERT_EQ(0x6001000U, page_start(0x6001fff));
+  } else if (kPageSize == 16384) {
+    ASSERT_EQ(0x0004000U, page_start(0x0004000));
+    ASSERT_EQ(0x3008000U, page_start(0x300822f));
+    ASSERT_EQ(0x6004000U, page_start(0x6004fff));
+  } else {
+    FAIL() << "Page size not supported " << kPageSize;
+  }
 }
 
 TEST(linker_utils, page_offset) {
-  ASSERT_EQ(0x0U, page_offset(0x0001000));
-  ASSERT_EQ(0x22fU, page_offset(0x300222f));
-  ASSERT_EQ(0xfffU, page_offset(0x6001fff));
+  const size_t kPageSize = page_size();
+
+  if (kPageSize == 4096) {
+    ASSERT_EQ(0x0U, page_offset(0x0001000));
+    ASSERT_EQ(0x22fU, page_offset(0x30222f));
+    ASSERT_EQ(0xfffU, page_offset(0x6001fff));
+  } else if (kPageSize == 16384) {
+    ASSERT_EQ(0x0U, page_offset(0x0004000));
+    ASSERT_EQ(0x322fU, page_offset(0x30322f));
+    ASSERT_EQ(0x3fffU, page_offset(0x6003fff));
+  } else {
+    FAIL() << "Page size not supported " << kPageSize;
+  }
 }
 
 TEST(linker_utils, safe_add) {
diff --git a/tests/Android.bp b/tests/Android.bp
index 14b4e3e..a53418a 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -583,18 +583,6 @@
     shared: {
         enabled: false,
     },
-    cflags: [
-        "-fno-emulated-tls",
-    ],
-    // With fuzzer builds, compiler instrumentation generates a reference to the
-    // __sancov_lowest_stack variable, which (for now) is defined by the fuzzer
-    // library as an emutls symbol. The -fno-emulated-tls flag above configures
-    // the compiler to reference an ordinary ELF TLS __sancov_lowest_stack
-    // symbol instead, which isn't defined. Disable the fuzzer for this test
-    // until the platform is switched to ELF TLS.
-    sanitize: {
-        fuzzer: false,
-    },
 }
 
 cc_test_library {
@@ -613,18 +601,6 @@
     shared: {
         enabled: false,
     },
-    cflags: [
-        "-fno-emulated-tls",
-    ],
-    // With fuzzer builds, compiler instrumentation generates a reference to the
-    // __sancov_lowest_stack variable, which (for now) is defined by the fuzzer
-    // library as an emutls symbol. The -fno-emulated-tls flag above configures
-    // the compiler to reference an ordinary ELF TLS __sancov_lowest_stack
-    // symbol instead, which isn't defined. Disable the fuzzer for this test
-    // until the platform is switched to ELF TLS.
-    sanitize: {
-        fuzzer: false,
-    },
 }
 
 cc_test_library {
diff --git a/tests/libs/Android.bp b/tests/libs/Android.bp
index 5d3a3b9..0bef469 100644
--- a/tests/libs/Android.bp
+++ b/tests/libs/Android.bp
@@ -34,7 +34,6 @@
     gtest: false,
     sanitize: {
         address: false,
-        fuzzer: false,
     },
     stl: "libc++_static",
     target: {
@@ -54,14 +53,12 @@
     name: "libtest_elftls_shared_var",
     defaults: ["bionic_testlib_defaults"],
     srcs: ["elftls_shared_var.cpp"],
-    cflags: ["-fno-emulated-tls"],
 }
 
 cc_test_library {
     name: "libtest_elftls_shared_var_ie",
     defaults: ["bionic_testlib_defaults"],
     srcs: ["elftls_shared_var_ie.cpp"],
-    cflags: ["-fno-emulated-tls"],
     shared_libs: ["libtest_elftls_shared_var"],
 }
 
@@ -69,7 +66,6 @@
     name: "libtest_elftls_tprel",
     defaults: ["bionic_testlib_defaults"],
     srcs: ["elftls_tprel.cpp"],
-    cflags: ["-fno-emulated-tls"],
 }
 
 cc_test {
@@ -83,7 +79,6 @@
     name: "libtest_elftls_dynamic",
     defaults: ["bionic_testlib_defaults"],
     srcs: ["elftls_dynamic.cpp"],
-    cflags: ["-fno-emulated-tls"],
     shared_libs: ["libtest_elftls_shared_var"],
 }
 
@@ -91,14 +86,12 @@
    name: "thread_exit_cb_helper",
    defaults: ["bionic_testlib_defaults"],
    srcs: ["thread_exit_cb_helper.cpp"],
-   cflags: ["-fno-emulated-tls"],
 }
 
 cc_test {
    name: "tls_properties_helper",
    defaults: ["bionic_testlib_defaults"],
    srcs: ["tls_properties_helper.cpp"],
-   cflags: ["-fno-emulated-tls"],
    shared_libs: ["libtest_elftls_shared_var"],
 }
 
@@ -108,7 +101,6 @@
     defaults: ["bionic_testlib_defaults"],
     srcs: ["elftls_dynamic_filler.cpp"],
     cflags: [
-        "-fno-emulated-tls",
         "-DTLS_FILLER=100",
     ],
 }
@@ -118,7 +110,6 @@
     defaults: ["bionic_testlib_defaults"],
     srcs: ["elftls_dynamic_filler.cpp"],
     cflags: [
-        "-fno-emulated-tls",
         "-DTLS_FILLER=200",
     ],
 }
@@ -128,7 +119,6 @@
     defaults: ["bionic_testlib_defaults"],
     srcs: ["elftls_dynamic_filler.cpp"],
     cflags: [
-        "-fno-emulated-tls",
         "-DTLS_FILLER=300",
     ],
 }
@@ -646,7 +636,6 @@
     ],
     sanitize: {
         address: false,
-        fuzzer: false,
     },
     stl: "libc++_static",
     target: {
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index 73090e1..749d687 100644
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -25,6 +25,7 @@
 #include <stdio.h>
 #include <sys/cdefs.h>
 #include <sys/mman.h>
+#include <sys/param.h>
 #include <sys/prctl.h>
 #include <sys/resource.h>
 #include <sys/syscall.h>
@@ -784,7 +785,7 @@
   size_t guard_size;
   ASSERT_EQ(0, pthread_attr_getguardsize(&attributes, &guard_size));
   ASSERT_EQ(128U, guard_size);
-  ASSERT_EQ(4096U, GetActualGuardSize(attributes));
+  ASSERT_EQ(static_cast<unsigned long>(getpagesize()), GetActualGuardSize(attributes));
 }
 
 TEST(pthread, pthread_attr_setguardsize_reasonable) {
@@ -808,7 +809,7 @@
   size_t guard_size;
   ASSERT_EQ(0, pthread_attr_getguardsize(&attributes, &guard_size));
   ASSERT_EQ(32*1024U + 1, guard_size);
-  ASSERT_EQ(36*1024U, GetActualGuardSize(attributes));
+  ASSERT_EQ(roundup(32 * 1024U + 1, getpagesize()), GetActualGuardSize(attributes));
 }
 
 TEST(pthread, pthread_attr_setguardsize_enormous) {
diff --git a/tests/semaphore_test.cpp b/tests/semaphore_test.cpp
index 5b061be..5558134 100644
--- a/tests/semaphore_test.cpp
+++ b/tests/semaphore_test.cpp
@@ -52,7 +52,7 @@
 
   // Too large an initial value.
   errno = 0;
-  ASSERT_EQ(-1, sem_init(&s, 0, SEM_VALUE_MAX + 1));
+  ASSERT_EQ(-1, sem_init(&s, 0, static_cast<unsigned>(SEM_VALUE_MAX) + 1));
   ASSERT_ERRNO(EINVAL);
 
   ASSERT_EQ(0, sem_destroy(&s));
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index 6a94507..e9a3080 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -1127,8 +1127,8 @@
 
 TEST(UNISTD_TEST, sysconf_SC_ARG_MAX) {
   // Since Linux 2.6.23, ARG_MAX isn't a constant and depends on RLIMIT_STACK.
-  // See prepare_arg_pages() in the kernel for the gory details:
-  // https://elixir.bootlin.com/linux/v5.3.11/source/fs/exec.c#L451
+  // See setup_arg_pages() in the kernel for the gory details:
+  // https://elixir.bootlin.com/linux/v6.6.4/source/fs/exec.c#L749
 
   // Get our current limit, and set things up so we restore the limit.
   rlimit rl;
@@ -1145,19 +1145,24 @@
   // _SC_ARG_MAX should be 1/4 the stack size.
   EXPECT_EQ(static_cast<long>(rl.rlim_cur / 4), sysconf(_SC_ARG_MAX));
 
-  // If you have a really small stack, the kernel still guarantees "32 pages" (see fs/exec.c).
+  // If you have a really small stack, the kernel still guarantees a stack
+  // expansion of 128KiB (see setup_arg_pages() in fs/exec.c).
   rl.rlim_cur = 1024;
   rl.rlim_max = RLIM_INFINITY;
   ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl));
 
-  EXPECT_EQ(static_cast<long>(32 * sysconf(_SC_PAGE_SIZE)), sysconf(_SC_ARG_MAX));
+  // The stack expansion number is defined in fs/exec.c.
+  // https://elixir.bootlin.com/linux/v6.6.4/source/fs/exec.c#L845
+  constexpr long kernel_stack_expansion = 131072;
+  EXPECT_EQ(kernel_stack_expansion, sysconf(_SC_ARG_MAX));
 
-  // With a 128-page stack limit, we know exactly what _SC_ARG_MAX should be...
-  rl.rlim_cur = 128 * sysconf(_SC_PAGE_SIZE);
+  // If you have a large stack, the kernel will keep the stack
+  // expansion to 128KiB (see setup_arg_pages() in fs/exec.c).
+  rl.rlim_cur = 524288;
   rl.rlim_max = RLIM_INFINITY;
   ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl));
 
-  EXPECT_EQ(static_cast<long>((128 * sysconf(_SC_PAGE_SIZE)) / 4), sysconf(_SC_ARG_MAX));
+  EXPECT_EQ(kernel_stack_expansion, sysconf(_SC_ARG_MAX));
 }
 
 TEST(UNISTD_TEST, sysconf_unknown) {