[libc-commits] [libc] [libc] fix sysconf test for rv32 (PR #162685)

Schrodinger ZHU Yifan via libc-commits libc-commits at lists.llvm.org
Thu Oct 9 10:39:50 PDT 2025


https://github.com/SchrodingerZhu updated https://github.com/llvm/llvm-project/pull/162685

>From 06b1f1176f60f172adebc5ff36999d94cf942c4d Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <yifanzhu at rochester.edu>
Date: Thu, 9 Oct 2025 11:49:42 -0400
Subject: [PATCH 1/2] [libc] fix sysconf test for rv32

---
 libc/src/__support/OSUtil/linux/auxv.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libc/src/__support/OSUtil/linux/auxv.h b/libc/src/__support/OSUtil/linux/auxv.h
index 894868ae5824d..cca0f358e2366 100644
--- a/libc/src/__support/OSUtil/linux/auxv.h
+++ b/libc/src/__support/OSUtil/linux/auxv.h
@@ -16,6 +16,7 @@
 
 #include <linux/auxvec.h> // For AT_ macros
 #include <linux/mman.h>   // For mmap flags
+#include <linux/param.h>  // For EXEC_PAGESIZE
 #include <linux/prctl.h>  // For prctl
 #include <sys/syscall.h>  // For syscall numbers
 
@@ -90,7 +91,7 @@ LIBC_INLINE void Vector::fallback_initialize_unsync() {
                                      PROT_READ | PROT_WRITE,
                                      MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
   // We do not proceed if mmap fails.
-  if (mmap_ret <= 0)
+  if (mmap_ret <= 0 && mmap_ret > -EXEC_PAGESIZE)
     return;
 
   // Initialize the auxv array with AT_NULL entries.

>From 88d0f002e2f8d16bb3660749c210d7eb8fc2da36 Mon Sep 17 00:00:00 2001
From: Schrodinger ZHU Yifan <yifanzhu at rochester.edu>
Date: Thu, 9 Oct 2025 13:39:21 -0400
Subject: [PATCH 2/2] [libc] address CRs

---
 libc/src/__support/OSUtil/linux/auxv.h      |  2 +-
 libc/src/__support/OSUtil/linux/syscall.h   | 14 ++++++++++++++
 libc/src/__support/threads/linux/thread.cpp |  2 +-
 libc/src/sys/mman/linux/mmap.cpp            |  2 +-
 libc/startup/linux/aarch64/tls.cpp          |  2 +-
 libc/startup/linux/riscv/tls.cpp            |  2 +-
 libc/startup/linux/x86_64/tls.cpp           |  2 +-
 7 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/libc/src/__support/OSUtil/linux/auxv.h b/libc/src/__support/OSUtil/linux/auxv.h
index cca0f358e2366..9c07c544be241 100644
--- a/libc/src/__support/OSUtil/linux/auxv.h
+++ b/libc/src/__support/OSUtil/linux/auxv.h
@@ -91,7 +91,7 @@ LIBC_INLINE void Vector::fallback_initialize_unsync() {
                                      PROT_READ | PROT_WRITE,
                                      MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
   // We do not proceed if mmap fails.
-  if (mmap_ret <= 0 && mmap_ret > -EXEC_PAGESIZE)
+  if (!linux_utils::is_valid_mmap(mmap_ret))
     return;
 
   // Initialize the auxv array with AT_NULL entries.
diff --git a/libc/src/__support/OSUtil/linux/syscall.h b/libc/src/__support/OSUtil/linux/syscall.h
index 24e0fca73c167..02c0473014018 100644
--- a/libc/src/__support/OSUtil/linux/syscall.h
+++ b/libc/src/__support/OSUtil/linux/syscall.h
@@ -34,6 +34,20 @@ LIBC_INLINE R syscall_impl(long __number, Ts... ts) {
   return cpp::bit_or_static_cast<R>(syscall_impl(__number, (long)ts...));
 }
 
+// Linux-specific function for checking
+namespace linux_utils {
+LIBC_INLINE_VAR constexpr unsigned long MAX_ERRNO = 4095;
+// Ideally, this should be defined using PAGE_OFFSET
+// However, that is a configurable parameter. We mimic kernel's behavior
+// by checking against MAX_ERRNO.
+template <typename PointerLike>
+LIBC_INLINE constexpr bool is_valid_mmap(PointerLike ptr) {
+  long addr = cpp::bit_cast<long>(ptr);
+  return __builtin_expect(addr > 0 || addr < -cpp::bit_cast<long>(MAX_ERRNO),
+                          true);
+}
+} // namespace linux_utils
+
 } // namespace LIBC_NAMESPACE_DECL
 
 #endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_SYSCALL_H
diff --git a/libc/src/__support/threads/linux/thread.cpp b/libc/src/__support/threads/linux/thread.cpp
index d9e479eefcaef..4f1e9110457d9 100644
--- a/libc/src/__support/threads/linux/thread.cpp
+++ b/libc/src/__support/threads/linux/thread.cpp
@@ -100,7 +100,7 @@ LIBC_INLINE ErrorOr<void *> alloc_stack(size_t stacksize, size_t guardsize) {
       -1,                          // Not backed by any file
       0                            // No offset
   );
-  if (mmap_result < 0 && (uintptr_t(mmap_result) >= UINTPTR_MAX - size))
+  if (!linux_utils::is_valid_mmap(mmap_result))
     return Error{int(-mmap_result)};
 
   if (guardsize) {
diff --git a/libc/src/sys/mman/linux/mmap.cpp b/libc/src/sys/mman/linux/mmap.cpp
index 33f9fe8ff3709..76a6611e2b329 100644
--- a/libc/src/sys/mman/linux/mmap.cpp
+++ b/libc/src/sys/mman/linux/mmap.cpp
@@ -56,7 +56,7 @@ LLVM_LIBC_FUNCTION(void *, mmap,
   // However, since a valid return address cannot be within the last page, a
   // return value corresponding to a location in the last page is an error
   // value.
-  if (ret < 0 && ret > -EXEC_PAGESIZE) {
+  if (!linux_utils::is_valid_mmap(ret)) {
     libc_errno = static_cast<int>(-ret);
     return MAP_FAILED;
   }
diff --git a/libc/startup/linux/aarch64/tls.cpp b/libc/startup/linux/aarch64/tls.cpp
index ea1b50c9fb209..7847797c13bd4 100644
--- a/libc/startup/linux/aarch64/tls.cpp
+++ b/libc/startup/linux/aarch64/tls.cpp
@@ -62,7 +62,7 @@ void init_tls(TLSDescriptor &tls_descriptor) {
                                          MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
   // We cannot check the return value with MAP_FAILED as that is the return
   // of the mmap function and not the mmap syscall.
-  if (mmap_ret_val < 0 && static_cast<uintptr_t>(mmap_ret_val) > -app.page_size)
+  if (!linux_utils::is_valid_mmap(mmap_ret_val))
     syscall_impl<long>(SYS_exit, 1);
   uintptr_t thread_ptr = uintptr_t(reinterpret_cast<uintptr_t *>(mmap_ret_val));
   uintptr_t tls_addr = thread_ptr + size_of_pointers + padding;
diff --git a/libc/startup/linux/riscv/tls.cpp b/libc/startup/linux/riscv/tls.cpp
index 04d44e6ca882e..e9d23c5b17b1e 100644
--- a/libc/startup/linux/riscv/tls.cpp
+++ b/libc/startup/linux/riscv/tls.cpp
@@ -50,7 +50,7 @@ void init_tls(TLSDescriptor &tls_descriptor) {
                                          MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
   // We cannot check the return value with MAP_FAILED as that is the return
   // of the mmap function and not the mmap syscall.
-  if (mmap_ret_val < 0 && static_cast<uintptr_t>(mmap_ret_val) > -app.page_size)
+  if (!linux_utils::is_valid_mmap(mmap_ret_val))
     syscall_impl<long>(SYS_exit, 1);
   uintptr_t thread_ptr = uintptr_t(reinterpret_cast<uintptr_t *>(mmap_ret_val));
   uintptr_t tls_addr = thread_ptr + size_of_pointers + padding;
diff --git a/libc/startup/linux/x86_64/tls.cpp b/libc/startup/linux/x86_64/tls.cpp
index d6b549a2e6c46..497f744e89e28 100644
--- a/libc/startup/linux/x86_64/tls.cpp
+++ b/libc/startup/linux/x86_64/tls.cpp
@@ -53,7 +53,7 @@ void init_tls(TLSDescriptor &tls_descriptor) {
       MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
   // We cannot check the return value with MAP_FAILED as that is the return
   // of the mmap function and not the mmap syscall.
-  if (mmap_retval < 0 && static_cast<uintptr_t>(mmap_retval) > -app.page_size)
+  if (!linux_utils::is_valid_mmap(mmap_retval))
     syscall_impl<long>(SYS_exit, 1);
   uintptr_t *tls_addr = reinterpret_cast<uintptr_t *>(mmap_retval);
 



More information about the libc-commits mailing list