[libc-commits] [libc] [libc] Refactoring getauxval to use internal functions (PR #144451)

Uzair Nawaz via libc-commits libc-commits at lists.llvm.org
Tue Jun 17 13:30:38 PDT 2025


https://github.com/uzairnawaz updated https://github.com/llvm/llvm-project/pull/144451

>From c0cb968758f6eb58b255aaddd503473bbe51b51a Mon Sep 17 00:00:00 2001
From: Uzair Nawaz <uzairnawaz at google.com>
Date: Mon, 16 Jun 2025 16:53:04 +0000
Subject: [PATCH 01/11] made mmap an internal function; called internal
 function in getauxval

---
 .../src/__support/OSUtil/linux/CMakeLists.txt |  1 +
 libc/src/__support/OSUtil/linux/mmap.cpp      | 66 +++++++++++++++++++
 libc/src/__support/OSUtil/mmap.h              | 23 +++++++
 libc/src/sys/auxv/linux/CMakeLists.txt        |  2 +-
 libc/src/sys/auxv/linux/getauxval.cpp         |  6 +-
 libc/src/sys/mman/linux/CMakeLists.txt        |  3 -
 libc/src/sys/mman/linux/mmap.cpp              | 50 +-------------
 7 files changed, 97 insertions(+), 54 deletions(-)
 create mode 100644 libc/src/__support/OSUtil/linux/mmap.cpp
 create mode 100644 libc/src/__support/OSUtil/mmap.h

diff --git a/libc/src/__support/OSUtil/linux/CMakeLists.txt b/libc/src/__support/OSUtil/linux/CMakeLists.txt
index b9704d42cd33b..9ff47eab858de 100644
--- a/libc/src/__support/OSUtil/linux/CMakeLists.txt
+++ b/libc/src/__support/OSUtil/linux/CMakeLists.txt
@@ -9,6 +9,7 @@ add_object_library(
   SRCS
     exit.cpp
     fcntl.cpp
+    mmap.cpp
   HDRS
     io.h
     syscall.h
diff --git a/libc/src/__support/OSUtil/linux/mmap.cpp b/libc/src/__support/OSUtil/linux/mmap.cpp
new file mode 100644
index 0000000000000..81b4457812785
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/mmap.cpp
@@ -0,0 +1,66 @@
+//===------ Linux implementation of the POSIX mmap function -----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/OSUtil/mmap.h"
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/common.h"
+
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+#include <linux/param.h> // For EXEC_PAGESIZE.
+#include <sys/syscall.h> // For syscall numbers.
+
+namespace LIBC_NAMESPACE_DECL {
+namespace internal {
+    
+// This function is currently linux only. It has to be refactored suitably if
+// mmap is to be supported on non-linux operating systems also.
+void *mmap(void *addr, size_t size, int prot, int flags, int fd, off_t offset) {
+  // A lot of POSIX standard prescribed validation of the parameters is not
+  // done in this function as modern linux versions do it in the syscall.
+  // TODO: Perform argument validation not done by the linux syscall.
+
+  // EXEC_PAGESIZE is used for the page size. While this is OK for x86_64, it
+  // might not be correct in general.
+  // TODO: Use pagesize read from the ELF aux vector instead of EXEC_PAGESIZE.
+
+#ifdef SYS_mmap2
+  offset /= EXEC_PAGESIZE;
+  long syscall_number = SYS_mmap2;
+#elif defined(SYS_mmap)
+  long syscall_number = SYS_mmap;
+#else
+#error "mmap or mmap2 syscalls not available."
+#endif
+
+  // We add an explicit cast to silence a "implicit conversion loses integer
+  // precision" warning when compiling for 32-bit systems.
+  long mmap_offset = static_cast<long>(offset);
+  long ret =
+      LIBC_NAMESPACE::syscall_impl(syscall_number, reinterpret_cast<long>(addr),
+                                   size, prot, flags, fd, mmap_offset);
+
+  // The mmap/mmap2 syscalls return negative values on error. These negative
+  // values are actually the negative values of the error codes. So, fix them
+  // up in case an error code is detected.
+  //
+  // A point to keep in mind for the fix up is that a negative return value
+  // from the syscall can also be an error-free value returned by the syscall.
+  // 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) {
+    libc_errno = static_cast<int>(-ret);
+    return MAP_FAILED;
+  }
+
+  return reinterpret_cast<void *>(ret);
+}
+
+} // namespace internal
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/__support/OSUtil/mmap.h b/libc/src/__support/OSUtil/mmap.h
new file mode 100644
index 0000000000000..45bbab22f4cda
--- /dev/null
+++ b/libc/src/__support/OSUtil/mmap.h
@@ -0,0 +1,23 @@
+//===----------- Implementation header of the mmap function -----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_MMAP_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_MMAP_H
+
+#include "src/__support/macros/config.h"
+#include <sys/mman.h> // For size_t and off_t
+
+namespace LIBC_NAMESPACE_DECL {
+namespace internal {
+
+void *mmap(void *addr, size_t size, int prot, int flags, int fd, off_t offset);
+
+} // namespace internal
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_MMAP_H
diff --git a/libc/src/sys/auxv/linux/CMakeLists.txt b/libc/src/sys/auxv/linux/CMakeLists.txt
index 4884184cc6053..072b00f80b54d 100644
--- a/libc/src/sys/auxv/linux/CMakeLists.txt
+++ b/libc/src/sys/auxv/linux/CMakeLists.txt
@@ -6,10 +6,10 @@ add_entrypoint_object(
     ../getauxval.h
   DEPENDS
     libc.src.sys.prctl.prctl
-    libc.src.sys.mman.mmap
     libc.src.sys.mman.munmap
     libc.src.__support.threads.callonce
     libc.src.__support.common
+    libc.src.__support.OSUtil.osutil
     libc.src.errno.errno
     libc.config.app_h
     libc.src.fcntl.open
diff --git a/libc/src/sys/auxv/linux/getauxval.cpp b/libc/src/sys/auxv/linux/getauxval.cpp
index f3ae7c5c4e07a..41b46e20587b6 100644
--- a/libc/src/sys/auxv/linux/getauxval.cpp
+++ b/libc/src/sys/auxv/linux/getauxval.cpp
@@ -18,7 +18,7 @@
 #include "src/__support/threads/linux/futex_word.h"
 
 // for mallocing the global auxv
-#include "src/sys/mman/mmap.h"
+#include "src/__support/OSUtil/mmap.h"
 #include "src/sys/mman/munmap.h"
 
 // for reading /proc/self/auxv
@@ -60,8 +60,8 @@ class AuxvMMapGuard {
   constexpr static size_t AUXV_MMAP_SIZE = sizeof(AuxEntry) * MAX_AUXV_ENTRIES;
 
   AuxvMMapGuard()
-      : ptr(mmap(nullptr, AUXV_MMAP_SIZE, PROT_READ | PROT_WRITE,
-                 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) {}
+      : ptr(internal::mmap(nullptr, AUXV_MMAP_SIZE, PROT_READ | PROT_WRITE,
+                           MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) {}
   ~AuxvMMapGuard() {
     if (ptr != MAP_FAILED)
       munmap(ptr, AUXV_MMAP_SIZE);
diff --git a/libc/src/sys/mman/linux/CMakeLists.txt b/libc/src/sys/mman/linux/CMakeLists.txt
index 89a0ad1527a06..affb3c672a460 100644
--- a/libc/src/sys/mman/linux/CMakeLists.txt
+++ b/libc/src/sys/mman/linux/CMakeLists.txt
@@ -18,10 +18,7 @@ add_entrypoint_object(
   HDRS
     ../mmap.h
   DEPENDS
-    libc.include.sys_mman
-    libc.include.sys_syscall
     libc.src.__support.OSUtil.osutil
-    libc.src.errno.errno
 )
 
 add_entrypoint_object(
diff --git a/libc/src/sys/mman/linux/mmap.cpp b/libc/src/sys/mman/linux/mmap.cpp
index 33f9fe8ff3709..811c3541768e0 100644
--- a/libc/src/sys/mman/linux/mmap.cpp
+++ b/libc/src/sys/mman/linux/mmap.cpp
@@ -8,60 +8,16 @@
 
 #include "src/sys/mman/mmap.h"
 
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/OSUtil/mmap.h"
 #include "src/__support/common.h"
 
-#include "src/__support/libc_errno.h"
-#include "src/__support/macros/config.h"
-#include <linux/param.h> // For EXEC_PAGESIZE.
-#include <sys/syscall.h> // For syscall numbers.
-
 namespace LIBC_NAMESPACE_DECL {
 
-// This function is currently linux only. It has to be refactored suitably if
-// mmap is to be supported on non-linux operating systems also.
+
 LLVM_LIBC_FUNCTION(void *, mmap,
                    (void *addr, size_t size, int prot, int flags, int fd,
                     off_t offset)) {
-  // A lot of POSIX standard prescribed validation of the parameters is not
-  // done in this function as modern linux versions do it in the syscall.
-  // TODO: Perform argument validation not done by the linux syscall.
-
-  // EXEC_PAGESIZE is used for the page size. While this is OK for x86_64, it
-  // might not be correct in general.
-  // TODO: Use pagesize read from the ELF aux vector instead of EXEC_PAGESIZE.
-
-#ifdef SYS_mmap2
-  offset /= EXEC_PAGESIZE;
-  long syscall_number = SYS_mmap2;
-#elif defined(SYS_mmap)
-  long syscall_number = SYS_mmap;
-#else
-#error "mmap or mmap2 syscalls not available."
-#endif
-
-  // We add an explicit cast to silence a "implicit conversion loses integer
-  // precision" warning when compiling for 32-bit systems.
-  long mmap_offset = static_cast<long>(offset);
-  long ret =
-      LIBC_NAMESPACE::syscall_impl(syscall_number, reinterpret_cast<long>(addr),
-                                   size, prot, flags, fd, mmap_offset);
-
-  // The mmap/mmap2 syscalls return negative values on error. These negative
-  // values are actually the negative values of the error codes. So, fix them
-  // up in case an error code is detected.
-  //
-  // A point to keep in mind for the fix up is that a negative return value
-  // from the syscall can also be an error-free value returned by the syscall.
-  // 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) {
-    libc_errno = static_cast<int>(-ret);
-    return MAP_FAILED;
-  }
-
-  return reinterpret_cast<void *>(ret);
+  return internal::mmap(addr, size, prot, flags, fd, offset);
 }
 
 } // namespace LIBC_NAMESPACE_DECL

>From d110ef55afc414929327ef44fd55f09d356e1761 Mon Sep 17 00:00:00 2001
From: Uzair Nawaz <uzairnawaz at google.com>
Date: Mon, 16 Jun 2025 17:11:44 +0000
Subject: [PATCH 02/11] refactored to make munmap an internal function

---
 .../src/__support/OSUtil/linux/CMakeLists.txt |  1 +
 libc/src/__support/OSUtil/linux/munmap.cpp    | 37 +++++++++++++++++++
 libc/src/__support/OSUtil/munmap.h            | 23 ++++++++++++
 libc/src/sys/auxv/linux/CMakeLists.txt        |  1 -
 libc/src/sys/auxv/linux/getauxval.cpp         |  6 +--
 libc/src/sys/mman/linux/CMakeLists.txt        |  3 --
 libc/src/sys/mman/linux/munmap.cpp            | 20 +---------
 7 files changed, 66 insertions(+), 25 deletions(-)
 create mode 100644 libc/src/__support/OSUtil/linux/munmap.cpp
 create mode 100644 libc/src/__support/OSUtil/munmap.h

diff --git a/libc/src/__support/OSUtil/linux/CMakeLists.txt b/libc/src/__support/OSUtil/linux/CMakeLists.txt
index 9ff47eab858de..a7af63e4aa7c3 100644
--- a/libc/src/__support/OSUtil/linux/CMakeLists.txt
+++ b/libc/src/__support/OSUtil/linux/CMakeLists.txt
@@ -10,6 +10,7 @@ add_object_library(
     exit.cpp
     fcntl.cpp
     mmap.cpp
+    munmap.cpp
   HDRS
     io.h
     syscall.h
diff --git a/libc/src/__support/OSUtil/linux/munmap.cpp b/libc/src/__support/OSUtil/linux/munmap.cpp
new file mode 100644
index 0000000000000..15bfc514b493e
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/munmap.cpp
@@ -0,0 +1,37 @@
+//===---- Linux implementation of the POSIX munmap function -----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/OSUtil/munmap.h"
+
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/common.h"
+
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h> // For syscall numbers.
+
+namespace LIBC_NAMESPACE_DECL {
+namespace internal {
+
+// This function is currently linux only. It has to be refactored suitably if
+// munmap is to be supported on non-linux operating systems also.
+int munmap(void *addr, size_t size) {
+  int ret = LIBC_NAMESPACE::syscall_impl<int>(
+      SYS_munmap, reinterpret_cast<long>(addr), size);
+
+  // A negative return value indicates an error with the magnitude of the
+  // value being the error code.
+  if (ret < 0) {
+    libc_errno = -ret;
+    return -1;
+  }
+
+  return 0;
+}
+} // namespace internal
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/__support/OSUtil/munmap.h b/libc/src/__support/OSUtil/munmap.h
new file mode 100644
index 0000000000000..b279ecfcb49d3
--- /dev/null
+++ b/libc/src/__support/OSUtil/munmap.h
@@ -0,0 +1,23 @@
+//===--------- Implementation header of the munmap function -----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_MUNMAP_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_MUNMAP_H
+
+#include "src/__support/macros/config.h"
+#include <sys/mman.h> // For size_t and off_t
+
+namespace LIBC_NAMESPACE_DECL {
+namespace internal {
+
+int munmap(void *addr, size_t size);
+
+} // namespace internal
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_MUNMAP_H
diff --git a/libc/src/sys/auxv/linux/CMakeLists.txt b/libc/src/sys/auxv/linux/CMakeLists.txt
index 072b00f80b54d..d21754874830d 100644
--- a/libc/src/sys/auxv/linux/CMakeLists.txt
+++ b/libc/src/sys/auxv/linux/CMakeLists.txt
@@ -6,7 +6,6 @@ add_entrypoint_object(
     ../getauxval.h
   DEPENDS
     libc.src.sys.prctl.prctl
-    libc.src.sys.mman.munmap
     libc.src.__support.threads.callonce
     libc.src.__support.common
     libc.src.__support.OSUtil.osutil
diff --git a/libc/src/sys/auxv/linux/getauxval.cpp b/libc/src/sys/auxv/linux/getauxval.cpp
index 41b46e20587b6..44ac4d041c19a 100644
--- a/libc/src/sys/auxv/linux/getauxval.cpp
+++ b/libc/src/sys/auxv/linux/getauxval.cpp
@@ -19,7 +19,7 @@
 
 // for mallocing the global auxv
 #include "src/__support/OSUtil/mmap.h"
-#include "src/sys/mman/munmap.h"
+#include "src/__support/OSUtil/munmap.h"
 
 // for reading /proc/self/auxv
 #include "src/fcntl/open.h"
@@ -64,13 +64,13 @@ class AuxvMMapGuard {
                            MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) {}
   ~AuxvMMapGuard() {
     if (ptr != MAP_FAILED)
-      munmap(ptr, AUXV_MMAP_SIZE);
+      internal::munmap(ptr, AUXV_MMAP_SIZE);
   }
   void submit_to_global() {
     // atexit may fail, we do not set it to global in that case.
     int ret = __cxa_atexit(
         [](void *) {
-          munmap(auxv, AUXV_MMAP_SIZE);
+          internal::munmap(auxv, AUXV_MMAP_SIZE);
           auxv = nullptr;
         },
         nullptr, nullptr);
diff --git a/libc/src/sys/mman/linux/CMakeLists.txt b/libc/src/sys/mman/linux/CMakeLists.txt
index affb3c672a460..6447af9a3ff8a 100644
--- a/libc/src/sys/mman/linux/CMakeLists.txt
+++ b/libc/src/sys/mman/linux/CMakeLists.txt
@@ -41,10 +41,7 @@ add_entrypoint_object(
   HDRS
     ../munmap.h
   DEPENDS
-    libc.include.sys_mman
-    libc.include.sys_syscall
     libc.src.__support.OSUtil.osutil
-    libc.src.errno.errno
 )
 
 add_entrypoint_object(
diff --git a/libc/src/sys/mman/linux/munmap.cpp b/libc/src/sys/mman/linux/munmap.cpp
index 61b1f1549dd18..ec9558855a83a 100644
--- a/libc/src/sys/mman/linux/munmap.cpp
+++ b/libc/src/sys/mman/linux/munmap.cpp
@@ -8,29 +8,13 @@
 
 #include "src/sys/mman/munmap.h"
 
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/OSUtil/munmap.h"
 #include "src/__support/common.h"
 
-#include "src/__support/libc_errno.h"
-#include "src/__support/macros/config.h"
-#include <sys/syscall.h> // For syscall numbers.
-
 namespace LIBC_NAMESPACE_DECL {
 
-// This function is currently linux only. It has to be refactored suitably if
-// mmap is to be supported on non-linux operating systems also.
 LLVM_LIBC_FUNCTION(int, munmap, (void *addr, size_t size)) {
-  int ret = LIBC_NAMESPACE::syscall_impl<int>(
-      SYS_munmap, reinterpret_cast<long>(addr), size);
-
-  // A negative return value indicates an error with the magnitude of the
-  // value being the error code.
-  if (ret < 0) {
-    libc_errno = -ret;
-    return -1;
-  }
-
-  return 0;
+  return internal::munmap(addr, size);
 }
 
 } // namespace LIBC_NAMESPACE_DECL

>From 192eadf5a735a766f2dadebcb3fe36c771bbc811 Mon Sep 17 00:00:00 2001
From: Uzair Nawaz <uzairnawaz at google.com>
Date: Mon, 16 Jun 2025 18:29:00 +0000
Subject: [PATCH 03/11] switching to erroror for internal functions, not
 complete

---
 .../src/__support/OSUtil/linux/CMakeLists.txt |  1 +
 libc/src/__support/OSUtil/linux/mmap.cpp      | 13 +++----
 libc/src/__support/OSUtil/linux/munmap.cpp    | 14 ++-----
 libc/src/__support/OSUtil/linux/prctl.cpp     | 39 +++++++++++++++++++
 libc/src/__support/OSUtil/mmap.h              |  3 +-
 libc/src/__support/OSUtil/prctl.h             | 25 ++++++++++++
 libc/src/sys/auxv/linux/getauxval.cpp         | 15 +++----
 libc/src/sys/mman/linux/CMakeLists.txt        |  2 +
 libc/src/sys/mman/linux/mmap.cpp              | 10 ++++-
 libc/src/sys/mman/linux/munmap.cpp            | 12 +++++-
 libc/src/sys/prctl/linux/prctl.cpp            | 24 ++++--------
 11 files changed, 113 insertions(+), 45 deletions(-)
 create mode 100644 libc/src/__support/OSUtil/linux/prctl.cpp
 create mode 100644 libc/src/__support/OSUtil/prctl.h

diff --git a/libc/src/__support/OSUtil/linux/CMakeLists.txt b/libc/src/__support/OSUtil/linux/CMakeLists.txt
index 498efb08c67ab..4be990a2b029a 100644
--- a/libc/src/__support/OSUtil/linux/CMakeLists.txt
+++ b/libc/src/__support/OSUtil/linux/CMakeLists.txt
@@ -11,6 +11,7 @@ add_object_library(
     fcntl.cpp
     mmap.cpp
     munmap.cpp
+    prctl.cpp
   HDRS
     io.h
     syscall.h
diff --git a/libc/src/__support/OSUtil/linux/mmap.cpp b/libc/src/__support/OSUtil/linux/mmap.cpp
index 81b4457812785..9e27701e73572 100644
--- a/libc/src/__support/OSUtil/linux/mmap.cpp
+++ b/libc/src/__support/OSUtil/linux/mmap.cpp
@@ -9,18 +9,19 @@
 #include "src/__support/OSUtil/mmap.h"
 #include "src/__support/OSUtil/syscall.h" // For internal syscall function.
 #include "src/__support/common.h"
+#include "src/__support/error_or.h"
 
-#include "src/__support/libc_errno.h"
 #include "src/__support/macros/config.h"
 #include <linux/param.h> // For EXEC_PAGESIZE.
 #include <sys/syscall.h> // For syscall numbers.
 
 namespace LIBC_NAMESPACE_DECL {
 namespace internal {
-    
+
 // This function is currently linux only. It has to be refactored suitably if
 // mmap is to be supported on non-linux operating systems also.
-void *mmap(void *addr, size_t size, int prot, int flags, int fd, off_t offset) {
+ErrorOr<void *> mmap(void *addr, size_t size, int prot, int flags, int fd,
+                     off_t offset) {
   // A lot of POSIX standard prescribed validation of the parameters is not
   // done in this function as modern linux versions do it in the syscall.
   // TODO: Perform argument validation not done by the linux syscall.
@@ -54,10 +55,8 @@ void *mmap(void *addr, size_t size, int prot, int flags, int fd, off_t offset) {
   // 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) {
-    libc_errno = static_cast<int>(-ret);
-    return MAP_FAILED;
-  }
+  if (ret < 0 && ret > -EXEC_PAGESIZE)
+    return Error(static_cast<int>(-ret));
 
   return reinterpret_cast<void *>(ret);
 }
diff --git a/libc/src/__support/OSUtil/linux/munmap.cpp b/libc/src/__support/OSUtil/linux/munmap.cpp
index 15bfc514b493e..199467c93c48e 100644
--- a/libc/src/__support/OSUtil/linux/munmap.cpp
+++ b/libc/src/__support/OSUtil/linux/munmap.cpp
@@ -21,17 +21,9 @@ namespace internal {
 // This function is currently linux only. It has to be refactored suitably if
 // munmap is to be supported on non-linux operating systems also.
 int munmap(void *addr, size_t size) {
-  int ret = LIBC_NAMESPACE::syscall_impl<int>(
-      SYS_munmap, reinterpret_cast<long>(addr), size);
-
-  // A negative return value indicates an error with the magnitude of the
-  // value being the error code.
-  if (ret < 0) {
-    libc_errno = -ret;
-    return -1;
-  }
-
-  return 0;
+  return LIBC_NAMESPACE::syscall_impl<int>(SYS_munmap,
+                                           reinterpret_cast<long>(addr), size);
 }
+
 } // namespace internal
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/__support/OSUtil/linux/prctl.cpp b/libc/src/__support/OSUtil/linux/prctl.cpp
new file mode 100644
index 0000000000000..1610fcbf2c402
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/prctl.cpp
@@ -0,0 +1,39 @@
+//===---- Linux implementation of the prctl function ------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/OSUtil/prctl.h"
+
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h> // For syscall numbers.
+
+namespace LIBC_NAMESPACE_DECL {
+namespace internal {
+
+ErrorOr<int> prctl(int option, unsigned long arg2, unsigned long arg3,
+          unsigned long arg4, unsigned long arg5) {
+  long ret =
+      LIBC_NAMESPACE::syscall_impl(SYS_prctl, option, arg2, arg3, arg4, arg5);
+
+  // The manpage states that "... return the nonnegative values described
+  // above. All other option values return 0 on success. On error,
+  // -1 is returned, and errno is set to indicate the error."
+  // According to the kernel implementation
+  // (https://github.com/torvalds/linux/blob/bee0e7762ad2c6025b9f5245c040fcc36ef2bde8/kernel/sys.c#L2442),
+  // return value from the syscall is set to 0 on default so we do not need to
+  // set the value on success manually.
+  if (ret < 0)
+    return Error(-ret);
+
+  return static_cast<int>(ret);
+}
+
+} // namespace internal
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/__support/OSUtil/mmap.h b/libc/src/__support/OSUtil/mmap.h
index 45bbab22f4cda..6d91bd5477f95 100644
--- a/libc/src/__support/OSUtil/mmap.h
+++ b/libc/src/__support/OSUtil/mmap.h
@@ -10,12 +10,13 @@
 #define LLVM_LIBC_SRC___SUPPORT_OSUTIL_MMAP_H
 
 #include "src/__support/macros/config.h"
+#include "src/__support/error_or.h"
 #include <sys/mman.h> // For size_t and off_t
 
 namespace LIBC_NAMESPACE_DECL {
 namespace internal {
 
-void *mmap(void *addr, size_t size, int prot, int flags, int fd, off_t offset);
+ErrorOr<void*> mmap(void *addr, size_t size, int prot, int flags, int fd, off_t offset);
 
 } // namespace internal
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/__support/OSUtil/prctl.h b/libc/src/__support/OSUtil/prctl.h
new file mode 100644
index 0000000000000..bbfe6323548e1
--- /dev/null
+++ b/libc/src/__support/OSUtil/prctl.h
@@ -0,0 +1,25 @@
+//===--------- Implementation header of the prctl function -----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_PRCTL_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_PRCTL_H
+
+#include "src/__support/macros/config.h"
+#include "src/__support/error_or.h"
+#include <sys/prctl.h>
+
+namespace LIBC_NAMESPACE_DECL {
+namespace internal {
+
+ErrorOr<int> prctl(int option, unsigned long arg2, unsigned long arg3,
+          unsigned long arg4, unsigned long arg5);
+
+} // namespace internal
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_PRCTL_H
diff --git a/libc/src/sys/auxv/linux/getauxval.cpp b/libc/src/sys/auxv/linux/getauxval.cpp
index 9d214f8ee576b..024642bb4fc67 100644
--- a/libc/src/sys/auxv/linux/getauxval.cpp
+++ b/libc/src/sys/auxv/linux/getauxval.cpp
@@ -12,6 +12,7 @@
 #include "src/__support/OSUtil/fcntl.h"
 #include "src/__support/common.h"
 #include "src/__support/libc_errno.h"
+#include "src/__support/error_or.h"
 #include "src/__support/macros/config.h"
 #include <linux/auxvec.h>
 
@@ -69,8 +70,8 @@ class AuxvMMapGuard {
       : ptr(internal::mmap(nullptr, AUXV_MMAP_SIZE, PROT_READ | PROT_WRITE,
                            MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) {}
   ~AuxvMMapGuard() {
-    if (ptr != MAP_FAILED)
-      internal::munmap(ptr, AUXV_MMAP_SIZE);
+    if (ptr.has_value())
+      internal::munmap(ptr.value(), AUXV_MMAP_SIZE);
   }
   void submit_to_global() {
     // atexit may fail, we do not set it to global in that case.
@@ -84,14 +85,14 @@ class AuxvMMapGuard {
     if (ret != 0)
       return;
 
-    auxv = reinterpret_cast<AuxEntry *>(ptr);
-    ptr = MAP_FAILED;
+    auxv = reinterpret_cast<AuxEntry *>(ptr.value());
+    ptr = Error(-1);
   }
-  bool allocated() const { return ptr != MAP_FAILED; }
-  void *get() const { return ptr; }
+  bool allocated() const { return ptr.has_value(); }
+  void *get() const { return ptr.value(); }
 
 private:
-  void *ptr;
+  ErrorOr<void*> ptr;
 };
 
 class AuxvFdGuard {
diff --git a/libc/src/sys/mman/linux/CMakeLists.txt b/libc/src/sys/mman/linux/CMakeLists.txt
index 6447af9a3ff8a..60421c47c4053 100644
--- a/libc/src/sys/mman/linux/CMakeLists.txt
+++ b/libc/src/sys/mman/linux/CMakeLists.txt
@@ -19,6 +19,7 @@ add_entrypoint_object(
     ../mmap.h
   DEPENDS
     libc.src.__support.OSUtil.osutil
+    libc.src.errno.errno
 )
 
 add_entrypoint_object(
@@ -42,6 +43,7 @@ add_entrypoint_object(
     ../munmap.h
   DEPENDS
     libc.src.__support.OSUtil.osutil
+    libc.src.errno.errno
 )
 
 add_entrypoint_object(
diff --git a/libc/src/sys/mman/linux/mmap.cpp b/libc/src/sys/mman/linux/mmap.cpp
index 811c3541768e0..e149a787fd67b 100644
--- a/libc/src/sys/mman/linux/mmap.cpp
+++ b/libc/src/sys/mman/linux/mmap.cpp
@@ -10,14 +10,20 @@
 
 #include "src/__support/OSUtil/mmap.h"
 #include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
-
 LLVM_LIBC_FUNCTION(void *, mmap,
                    (void *addr, size_t size, int prot, int flags, int fd,
                     off_t offset)) {
-  return internal::mmap(addr, size, prot, flags, fd, offset);
+  auto ptr = internal::mmap(addr, size, prot, flags, fd, offset);
+
+  if (ptr.has_value())
+    return ptr.value();
+
+  libc_errno = ptr.error();
+  return MAP_FAILED;
 }
 
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/sys/mman/linux/munmap.cpp b/libc/src/sys/mman/linux/munmap.cpp
index ec9558855a83a..c801989b9cdf6 100644
--- a/libc/src/sys/mman/linux/munmap.cpp
+++ b/libc/src/sys/mman/linux/munmap.cpp
@@ -10,11 +10,21 @@
 
 #include "src/__support/OSUtil/munmap.h"
 #include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(int, munmap, (void *addr, size_t size)) {
-  return internal::munmap(addr, size);
+  int ret = internal::munmap(addr, size);
+
+  // A negative return value indicates an error with the magnitude of the
+  // value being the error code.
+  if (ret < 0) {
+    libc_errno = -ret;
+    return -1;
+  }
+
+  return 0;
 }
 
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/sys/prctl/linux/prctl.cpp b/libc/src/sys/prctl/linux/prctl.cpp
index c726b0a539591..ca38a99923bbb 100644
--- a/libc/src/sys/prctl/linux/prctl.cpp
+++ b/libc/src/sys/prctl/linux/prctl.cpp
@@ -8,31 +8,23 @@
 
 #include "src/sys/prctl/prctl.h"
 
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
-
+#include "src/__support/OSUtil/prctl.h"
 #include "src/__support/libc_errno.h"
-#include "src/__support/macros/config.h"
-#include <sys/syscall.h> // For syscall numbers.
+#include "src/__support/common.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(int, prctl,
                    (int option, unsigned long arg2, unsigned long arg3,
                     unsigned long arg4, unsigned long arg5)) {
-  long ret =
-      LIBC_NAMESPACE::syscall_impl(SYS_prctl, option, arg2, arg3, arg4, arg5);
-  // The manpage states that "... return the nonnegative values described
-  // above. All other option values return 0 on success. On error,
-  // -1 is returned, and errno is set to indicate the error."
-  // According to the kernel implementation
-  // (https://github.com/torvalds/linux/blob/bee0e7762ad2c6025b9f5245c040fcc36ef2bde8/kernel/sys.c#L2442),
-  // return value from the syscall is set to 0 on default so we do not need to
-  // set the value on success manually.
-  if (ret < 0) {
-    libc_errno = static_cast<int>(-ret);
+  auto result = internal::prctl(option, arg2, arg3, arg4, arg5);
+
+  if (!result.has_value()) {
+    libc_errno = result.error();
     return -1;
   }
-  return static_cast<int>(ret);
+
+  return result.value();
 }
 
 } // namespace LIBC_NAMESPACE_DECL

>From 09363d4840910002dd0d6db1fdf691403cb6e715 Mon Sep 17 00:00:00 2001
From: Uzair Nawaz <uzairnawaz at google.com>
Date: Mon, 16 Jun 2025 20:17:45 +0000
Subject: [PATCH 04/11] switching to erroror for internal functions, not
 complete

---
 libc/src/__support/OSUtil/linux/prctl.cpp |  2 +-
 libc/src/__support/OSUtil/prctl.h         |  1 +
 libc/src/__support/wchar/wcrtomb.cpp      | 37 +++++++++++++++++++++++
 libc/src/sys/auxv/linux/getauxval.cpp     |  6 ++--
 libc/src/sys/prctl/linux/CMakeLists.txt   |  1 -
 5 files changed, 42 insertions(+), 5 deletions(-)
 create mode 100644 libc/src/__support/wchar/wcrtomb.cpp

diff --git a/libc/src/__support/OSUtil/linux/prctl.cpp b/libc/src/__support/OSUtil/linux/prctl.cpp
index 1610fcbf2c402..9f5f2d719c7f4 100644
--- a/libc/src/__support/OSUtil/linux/prctl.cpp
+++ b/libc/src/__support/OSUtil/linux/prctl.cpp
@@ -30,7 +30,7 @@ ErrorOr<int> prctl(int option, unsigned long arg2, unsigned long arg3,
   // return value from the syscall is set to 0 on default so we do not need to
   // set the value on success manually.
   if (ret < 0)
-    return Error(-ret);
+    return Error(static_cast<int>(-ret));
 
   return static_cast<int>(ret);
 }
diff --git a/libc/src/__support/OSUtil/prctl.h b/libc/src/__support/OSUtil/prctl.h
index bbfe6323548e1..cc0c85fa8fce7 100644
--- a/libc/src/__support/OSUtil/prctl.h
+++ b/libc/src/__support/OSUtil/prctl.h
@@ -12,6 +12,7 @@
 #include "src/__support/macros/config.h"
 #include "src/__support/error_or.h"
 #include <sys/prctl.h>
+#include "src/__support/libc_errno.h"
 
 namespace LIBC_NAMESPACE_DECL {
 namespace internal {
diff --git a/libc/src/__support/wchar/wcrtomb.cpp b/libc/src/__support/wchar/wcrtomb.cpp
new file mode 100644
index 0000000000000..d7a1b3738a6ef
--- /dev/null
+++ b/libc/src/__support/wchar/wcrtomb.cpp
@@ -0,0 +1,37 @@
+
+namespace LIBC_NAMESPACE_DECL {
+namespace internal {
+    void utf32to8(char* out, wchar_t src) {
+        char u, v, w, x, y, z;
+        u = (src & (0xf << 20)) >> 20;
+        v = (src & (0xf << 16)) >> 16;
+        w = (src & (0xf << 12)) >> 12;
+        x = (src & (0xf <<  8)) >>  8;
+        y = (src & (0xf <<  4)) >>  4;
+        z = (src & (0xf <<  0)) >>  0;
+
+        if (src <= 0x7f) {
+            // 0yyyzzzz
+            out[0] = src;
+        }
+        else if (src <= 0x7ff) {
+            // 110xxxyy 10yyzzzz
+            out[0] = 0xC0 | (x << 2) | (y >> 2);
+            out[1] = 0x80 | ((y & 0x3) << 4) | z;
+        }
+        else if (src <= 0xffff) {
+            // 1110wwww 10xxxxyy 10yyzzzz
+            out[0] = 0xE0 | w;
+            out[1] = 0x80 | (x << 2) | (y >> 2);
+            out[2] = 0x80 | ((y & 0x3) << 4) | z;
+        }
+        else if (src <= 0x10ffff) {
+            // 11110uvv 10vvwwww 10xxxxyy 10yyzzzz
+            out[0] = 0xF0 | (u << 2) | (v >> 2);
+            out[1] = 0x80 | ((v & 0x3) << 4) | w;
+            out[2] = 0x80 | (x << 2) | (y >> 2);
+            out[3] = 0x80 | ((y & 0x3) << 4) | z;
+        }
+    }
+}
+}
diff --git a/libc/src/sys/auxv/linux/getauxval.cpp b/libc/src/sys/auxv/linux/getauxval.cpp
index 024642bb4fc67..da92cc1962c34 100644
--- a/libc/src/sys/auxv/linux/getauxval.cpp
+++ b/libc/src/sys/auxv/linux/getauxval.cpp
@@ -31,7 +31,7 @@
 #include "src/__support/OSUtil/munmap.h"
 
 // for reading /proc/self/auxv
-#include "src/sys/prctl/prctl.h"
+#include "src/__support/OSUtil/prctl.h"
 #include "src/unistd/read.h"
 
 // getauxval will work either with or without __cxa_atexit support.
@@ -133,9 +133,9 @@ static void initialize_auxv_once(void) {
   // is compiled and run on separate kernels, we also check the return value of
   // prctl.
 #ifdef PR_GET_AUXV
-  int ret = prctl(PR_GET_AUXV, reinterpret_cast<unsigned long>(ptr),
+  auto ret = internal::prctl(PR_GET_AUXV, reinterpret_cast<unsigned long>(ptr),
                   available_size, 0, 0);
-  if (ret >= 0) {
+  if (ret.has_value()) {
     mmap_guard.submit_to_global();
     return;
   }
diff --git a/libc/src/sys/prctl/linux/CMakeLists.txt b/libc/src/sys/prctl/linux/CMakeLists.txt
index 05d336441f4d0..58a6410b5c583 100644
--- a/libc/src/sys/prctl/linux/CMakeLists.txt
+++ b/libc/src/sys/prctl/linux/CMakeLists.txt
@@ -6,7 +6,6 @@ add_entrypoint_object(
     ../prctl.h
   DEPENDS
     libc.include.sys_prctl
-    libc.include.sys_syscall
     libc.src.__support.OSUtil.osutil
     libc.src.errno.errno
 )

>From f2fa63950207cb27eab57bc11b5f1fbcb092cbff Mon Sep 17 00:00:00 2001
From: Uzair Nawaz <uzairnawaz at google.com>
Date: Mon, 16 Jun 2025 22:36:12 +0000
Subject: [PATCH 05/11] made internal function for read; removed errno guard
 class in getauxval

---
 .../src/__support/OSUtil/linux/CMakeLists.txt |  5 ++
 libc/src/__support/OSUtil/linux/read.cpp      | 32 ++++++++++
 libc/src/__support/OSUtil/read.h              | 26 ++++++++
 libc/src/sys/auxv/linux/getauxval.cpp         | 59 ++++++-------------
 libc/src/unistd/linux/read.cpp                | 19 +++---
 5 files changed, 89 insertions(+), 52 deletions(-)
 create mode 100644 libc/src/__support/OSUtil/linux/read.cpp
 create mode 100644 libc/src/__support/OSUtil/read.h

diff --git a/libc/src/__support/OSUtil/linux/CMakeLists.txt b/libc/src/__support/OSUtil/linux/CMakeLists.txt
index 4be990a2b029a..5c3f0342b9d9f 100644
--- a/libc/src/__support/OSUtil/linux/CMakeLists.txt
+++ b/libc/src/__support/OSUtil/linux/CMakeLists.txt
@@ -12,6 +12,7 @@ add_object_library(
     mmap.cpp
     munmap.cpp
     prctl.cpp
+    read.cpp
   HDRS
     io.h
     syscall.h
@@ -25,6 +26,10 @@ add_object_library(
     libc.hdr.types.struct_f_owner_ex
     libc.hdr.types.off_t
     libc.include.sys_syscall
+    libc.src.__support.macros.sanitizer
+    libc.hdr.types.size_t
+    libc.hdr.types.ssize_t
+    libc.include.unistd
 )
 
 add_header_library(
diff --git a/libc/src/__support/OSUtil/linux/read.cpp b/libc/src/__support/OSUtil/linux/read.cpp
new file mode 100644
index 0000000000000..88b6c9c754f68
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/read.cpp
@@ -0,0 +1,32 @@
+//===-- Linux implementation of read --------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/OSUtil/read.h"
+
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/common.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/sanitizer.h" // for MSAN_UNPOISON
+#include <sys/syscall.h>                    // For syscall numbers.
+
+namespace LIBC_NAMESPACE_DECL {
+namespace internal {
+
+ErrorOr<ssize_t> read(int fd, void *buf, size_t count) {
+  ssize_t ret = LIBC_NAMESPACE::syscall_impl<ssize_t>(SYS_read, fd, buf, count);
+  if (ret < 0)
+    return Error(static_cast<int>(-ret));
+
+  // The cast is important since there is a check that dereferences the pointer
+  // which fails on void*.
+  MSAN_UNPOISON(reinterpret_cast<char *>(buf), count);
+  return ret;
+}
+
+} // namespace internal
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/__support/OSUtil/read.h b/libc/src/__support/OSUtil/read.h
new file mode 100644
index 0000000000000..0e29fc36cfa24
--- /dev/null
+++ b/libc/src/__support/OSUtil/read.h
@@ -0,0 +1,26 @@
+//===--------- Implementation header of the read function -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_READ_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_READ_H
+
+#include "hdr/types/size_t.h"
+#include "hdr/types/ssize_t.h"
+#include "hdr/unistd_macros.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/error_or.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace internal {
+
+ErrorOr<ssize_t> read(int fd, void *buf, size_t count);
+
+} // namespace internal
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_READ_H
diff --git a/libc/src/sys/auxv/linux/getauxval.cpp b/libc/src/sys/auxv/linux/getauxval.cpp
index da92cc1962c34..113aeb500b73e 100644
--- a/libc/src/sys/auxv/linux/getauxval.cpp
+++ b/libc/src/sys/auxv/linux/getauxval.cpp
@@ -11,8 +11,8 @@
 #include "hdr/fcntl_macros.h"
 #include "src/__support/OSUtil/fcntl.h"
 #include "src/__support/common.h"
-#include "src/__support/libc_errno.h"
 #include "src/__support/error_or.h"
+#include "src/__support/libc_errno.h"
 #include "src/__support/macros/config.h"
 #include <linux/auxvec.h>
 
@@ -20,19 +20,13 @@
 #include "src/__support/threads/callonce.h"
 #include "src/__support/threads/linux/futex_word.h"
 
-// -----------------------------------------------------------------------------
-// TODO: This file should not include other public libc functions. Calling other
-// public libc functions is an antipattern within LLVM-libc. This needs to be
-// cleaned up. DO NOT COPY THIS.
-// -----------------------------------------------------------------------------
-
 // for mallocing the global auxv
 #include "src/__support/OSUtil/mmap.h"
 #include "src/__support/OSUtil/munmap.h"
 
 // for reading /proc/self/auxv
 #include "src/__support/OSUtil/prctl.h"
-#include "src/unistd/read.h"
+#include "src/__support/OSUtil/read.h"
 
 // getauxval will work either with or without __cxa_atexit support.
 // In order to detect if __cxa_atexit is supported, we define a weak symbol.
@@ -47,18 +41,6 @@ namespace LIBC_NAMESPACE_DECL {
 
 constexpr static size_t MAX_AUXV_ENTRIES = 64;
 
-// Helper to recover or set errno
-class AuxvErrnoGuard {
-public:
-  AuxvErrnoGuard() : saved(libc_errno), failure(false) {}
-  ~AuxvErrnoGuard() { libc_errno = failure ? ENOENT : saved; }
-  void mark_failure() { failure = true; }
-
-private:
-  int saved;
-  bool failure;
-};
-
 // Helper to manage the memory
 static AuxEntry *auxv = nullptr;
 
@@ -92,7 +74,7 @@ class AuxvMMapGuard {
   void *get() const { return ptr.value(); }
 
 private:
-  ErrorOr<void*> ptr;
+  ErrorOr<void *> ptr;
 };
 
 class AuxvFdGuard {
@@ -134,7 +116,7 @@ static void initialize_auxv_once(void) {
   // prctl.
 #ifdef PR_GET_AUXV
   auto ret = internal::prctl(PR_GET_AUXV, reinterpret_cast<unsigned long>(ptr),
-                  available_size, 0, 0);
+                             available_size, 0, 0);
   if (ret.has_value()) {
     mmap_guard.submit_to_global();
     return;
@@ -144,23 +126,22 @@ static void initialize_auxv_once(void) {
   if (!fd_guard.valid())
     return;
   auto *buf = reinterpret_cast<char *>(ptr);
-  libc_errno = 0;
   bool error_detected = false;
   // Read until we use up all the available space or we finish reading the file.
   while (available_size != 0) {
-    ssize_t bytes_read =
-        LIBC_NAMESPACE::read(fd_guard.get(), buf, available_size);
-    if (bytes_read <= 0) {
-      if (libc_errno == EINTR)
+    auto bytes_read = internal::read(fd_guard.get(), buf, available_size);
+    if (!bytes_read.has_value() ||
+        (bytes_read.has_value() && bytes_read.value() == 0)) {
+      if (bytes_read.error() == EINTR)
         continue;
       // Now, we either have an non-recoverable error or we have reached the end
       // of the file. Mark `error_detected` accordingly.
-      if (bytes_read == -1)
+      if (!bytes_read.has_value())
         error_detected = true;
       break;
     }
-    buf += bytes_read;
-    available_size -= bytes_read;
+    buf += bytes_read.value();
+    available_size -= bytes_read.value();
   }
   // If we get out of the loop without an error, the auxv is ready.
   if (!error_detected)
@@ -172,17 +153,17 @@ static AuxEntry read_entry(int fd) {
   size_t size = sizeof(AuxEntry);
   char *ptr = reinterpret_cast<char *>(&buf);
   while (size > 0) {
-    ssize_t ret = LIBC_NAMESPACE::read(fd, ptr, size);
-    if (ret < 0) {
-      if (libc_errno == EINTR)
+    auto ret = internal::read(fd, ptr, size);
+    if (!ret.has_value()) {
+      if (ret.error() == EINTR)
         continue;
       // Error detected, return AT_NULL
       buf.id = AT_NULL;
       buf.value = AT_NULL;
       break;
     }
-    ptr += ret;
-    size -= ret;
+    ptr += ret.value();
+    size -= ret.value();
   }
   return buf;
 }
@@ -191,15 +172,13 @@ LLVM_LIBC_FUNCTION(unsigned long, getauxval, (unsigned long id)) {
   // Fast path when libc is loaded by its own initialization code. In this case,
   // app.auxv_ptr is already set to the auxv passed on the initial stack of the
   // process.
-  AuxvErrnoGuard errno_guard;
 
-  auto search_auxv = [&errno_guard](AuxEntry *auxv,
-                                    unsigned long id) -> AuxEntryType {
+  auto search_auxv = [](AuxEntry *auxv, unsigned long id) -> AuxEntryType {
     for (auto *ptr = auxv; ptr->id != AT_NULL; ptr++)
       if (ptr->id == id)
         return ptr->value;
 
-    errno_guard.mark_failure();
+    libc_errno = ENOENT;
     return AT_NULL;
   };
 
@@ -227,7 +206,7 @@ LLVM_LIBC_FUNCTION(unsigned long, getauxval, (unsigned long id)) {
   }
 
   // cannot find the entry after all methods, mark failure and return 0
-  errno_guard.mark_failure();
+  libc_errno = ENOENT;
   return AT_NULL;
 }
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/unistd/linux/read.cpp b/libc/src/unistd/linux/read.cpp
index 55676f3f7010a..2f8a991e5558c 100644
--- a/libc/src/unistd/linux/read.cpp
+++ b/libc/src/unistd/linux/read.cpp
@@ -8,25 +8,20 @@
 
 #include "src/unistd/read.h"
 
-#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
-#include "src/__support/common.h"
+#include "src/__support/OSUtil/read.h" // For internal syscall function.
 #include "src/__support/libc_errno.h"
-#include "src/__support/macros/config.h"
-#include "src/__support/macros/sanitizer.h" // for MSAN_UNPOISON
-#include <sys/syscall.h>                    // For syscall numbers.
+#include "src/__support/common.h"
 
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(ssize_t, read, (int fd, void *buf, size_t count)) {
-  ssize_t ret = LIBC_NAMESPACE::syscall_impl<ssize_t>(SYS_read, fd, buf, count);
-  if (ret < 0) {
-    libc_errno = static_cast<int>(-ret);
+  auto ret = internal::read(fd, buf, count);
+  if (!ret.has_value()) {
+    libc_errno = static_cast<int>(ret.error());
     return -1;
   }
-  // The cast is important since there is a check that dereferences the pointer
-  // which fails on void*.
-  MSAN_UNPOISON(reinterpret_cast<char *>(buf), count);
-  return ret;
+
+  return ret.value();
 }
 
 } // namespace LIBC_NAMESPACE_DECL

>From 30af3b2327031b4d03795d6c20e39c96116c6c23 Mon Sep 17 00:00:00 2001
From: Uzair Nawaz <uzairnawaz at google.com>
Date: Mon, 16 Jun 2025 22:40:22 +0000
Subject: [PATCH 06/11] accidentally commited file previously

---
 libc/src/__support/wchar/wcrtomb.cpp | 37 ----------------------------
 1 file changed, 37 deletions(-)
 delete mode 100644 libc/src/__support/wchar/wcrtomb.cpp

diff --git a/libc/src/__support/wchar/wcrtomb.cpp b/libc/src/__support/wchar/wcrtomb.cpp
deleted file mode 100644
index d7a1b3738a6ef..0000000000000
--- a/libc/src/__support/wchar/wcrtomb.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-
-namespace LIBC_NAMESPACE_DECL {
-namespace internal {
-    void utf32to8(char* out, wchar_t src) {
-        char u, v, w, x, y, z;
-        u = (src & (0xf << 20)) >> 20;
-        v = (src & (0xf << 16)) >> 16;
-        w = (src & (0xf << 12)) >> 12;
-        x = (src & (0xf <<  8)) >>  8;
-        y = (src & (0xf <<  4)) >>  4;
-        z = (src & (0xf <<  0)) >>  0;
-
-        if (src <= 0x7f) {
-            // 0yyyzzzz
-            out[0] = src;
-        }
-        else if (src <= 0x7ff) {
-            // 110xxxyy 10yyzzzz
-            out[0] = 0xC0 | (x << 2) | (y >> 2);
-            out[1] = 0x80 | ((y & 0x3) << 4) | z;
-        }
-        else if (src <= 0xffff) {
-            // 1110wwww 10xxxxyy 10yyzzzz
-            out[0] = 0xE0 | w;
-            out[1] = 0x80 | (x << 2) | (y >> 2);
-            out[2] = 0x80 | ((y & 0x3) << 4) | z;
-        }
-        else if (src <= 0x10ffff) {
-            // 11110uvv 10vvwwww 10xxxxyy 10yyzzzz
-            out[0] = 0xF0 | (u << 2) | (v >> 2);
-            out[1] = 0x80 | ((v & 0x3) << 4) | w;
-            out[2] = 0x80 | (x << 2) | (y >> 2);
-            out[3] = 0x80 | ((y & 0x3) << 4) | z;
-        }
-    }
-}
-}

>From 172dcd74e1b7fd62cebd58f5d3547d0dfa61bc6b Mon Sep 17 00:00:00 2001
From: Uzair Nawaz <uzairnawaz at google.com>
Date: Mon, 16 Jun 2025 22:55:29 +0000
Subject: [PATCH 07/11] changed munmap to return an ErrorOr

---
 libc/src/__support/OSUtil/linux/munmap.cpp | 13 +++++++++----
 libc/src/__support/OSUtil/munmap.h         |  3 ++-
 libc/src/__support/OSUtil/prctl.h          |  6 +++---
 libc/src/sys/auxv/linux/CMakeLists.txt     |  2 +-
 libc/src/sys/mman/linux/munmap.cpp         |  8 ++++----
 libc/src/sys/prctl/linux/prctl.cpp         |  2 +-
 6 files changed, 20 insertions(+), 14 deletions(-)

diff --git a/libc/src/__support/OSUtil/linux/munmap.cpp b/libc/src/__support/OSUtil/linux/munmap.cpp
index 199467c93c48e..6a11bae263f13 100644
--- a/libc/src/__support/OSUtil/linux/munmap.cpp
+++ b/libc/src/__support/OSUtil/linux/munmap.cpp
@@ -11,7 +11,7 @@
 #include "src/__support/OSUtil/syscall.h" // For internal syscall function.
 #include "src/__support/common.h"
 
-#include "src/__support/libc_errno.h"
+#include "src/__support/error_or.h"
 #include "src/__support/macros/config.h"
 #include <sys/syscall.h> // For syscall numbers.
 
@@ -20,9 +20,14 @@ namespace internal {
 
 // This function is currently linux only. It has to be refactored suitably if
 // munmap is to be supported on non-linux operating systems also.
-int munmap(void *addr, size_t size) {
-  return LIBC_NAMESPACE::syscall_impl<int>(SYS_munmap,
-                                           reinterpret_cast<long>(addr), size);
+ErrorOr<int> munmap(void *addr, size_t size) {
+  int ret = LIBC_NAMESPACE::syscall_impl<int>(
+      SYS_munmap, reinterpret_cast<long>(addr), size);
+
+  if (ret < 0)
+    return Error(-ret);
+
+  return 0;
 }
 
 } // namespace internal
diff --git a/libc/src/__support/OSUtil/munmap.h b/libc/src/__support/OSUtil/munmap.h
index b279ecfcb49d3..5e1a961f4d654 100644
--- a/libc/src/__support/OSUtil/munmap.h
+++ b/libc/src/__support/OSUtil/munmap.h
@@ -9,13 +9,14 @@
 #ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_MUNMAP_H
 #define LLVM_LIBC_SRC___SUPPORT_OSUTIL_MUNMAP_H
 
+#include "src/__support/error_or.h"
 #include "src/__support/macros/config.h"
 #include <sys/mman.h> // For size_t and off_t
 
 namespace LIBC_NAMESPACE_DECL {
 namespace internal {
 
-int munmap(void *addr, size_t size);
+ErrorOr<int> munmap(void *addr, size_t size);
 
 } // namespace internal
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/__support/OSUtil/prctl.h b/libc/src/__support/OSUtil/prctl.h
index cc0c85fa8fce7..fd8ddf0829985 100644
--- a/libc/src/__support/OSUtil/prctl.h
+++ b/libc/src/__support/OSUtil/prctl.h
@@ -9,16 +9,16 @@
 #ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_PRCTL_H
 #define LLVM_LIBC_SRC___SUPPORT_OSUTIL_PRCTL_H
 
-#include "src/__support/macros/config.h"
 #include "src/__support/error_or.h"
-#include <sys/prctl.h>
 #include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+#include <sys/prctl.h>
 
 namespace LIBC_NAMESPACE_DECL {
 namespace internal {
 
 ErrorOr<int> prctl(int option, unsigned long arg2, unsigned long arg3,
-          unsigned long arg4, unsigned long arg5);
+                   unsigned long arg4, unsigned long arg5);
 
 } // namespace internal
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/sys/auxv/linux/CMakeLists.txt b/libc/src/sys/auxv/linux/CMakeLists.txt
index d21754874830d..ab6f01a314f0e 100644
--- a/libc/src/sys/auxv/linux/CMakeLists.txt
+++ b/libc/src/sys/auxv/linux/CMakeLists.txt
@@ -15,4 +15,4 @@ add_entrypoint_object(
     libc.src.unistd.read
     libc.src.unistd.close
     libc.include.sys_auxv
-)
+)
\ No newline at end of file
diff --git a/libc/src/sys/mman/linux/munmap.cpp b/libc/src/sys/mman/linux/munmap.cpp
index c801989b9cdf6..34bbca3231f9c 100644
--- a/libc/src/sys/mman/linux/munmap.cpp
+++ b/libc/src/sys/mman/linux/munmap.cpp
@@ -15,16 +15,16 @@
 namespace LIBC_NAMESPACE_DECL {
 
 LLVM_LIBC_FUNCTION(int, munmap, (void *addr, size_t size)) {
-  int ret = internal::munmap(addr, size);
+  auto ret = internal::munmap(addr, size);
 
   // A negative return value indicates an error with the magnitude of the
   // value being the error code.
-  if (ret < 0) {
-    libc_errno = -ret;
+  if (!ret.has_value()) {
+    libc_errno = ret.error();
     return -1;
   }
 
-  return 0;
+  return ret.value();
 }
 
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/sys/prctl/linux/prctl.cpp b/libc/src/sys/prctl/linux/prctl.cpp
index ca38a99923bbb..2ee858df53f72 100644
--- a/libc/src/sys/prctl/linux/prctl.cpp
+++ b/libc/src/sys/prctl/linux/prctl.cpp
@@ -9,8 +9,8 @@
 #include "src/sys/prctl/prctl.h"
 
 #include "src/__support/OSUtil/prctl.h"
-#include "src/__support/libc_errno.h"
 #include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
 
 namespace LIBC_NAMESPACE_DECL {
 

>From 55b32ce6bf19d0bf932f13cb2c79cb76eeb3e1ba Mon Sep 17 00:00:00 2001
From: Uzair Nawaz <uzairnawaz at google.com>
Date: Mon, 16 Jun 2025 22:58:34 +0000
Subject: [PATCH 08/11] style

---
 libc/src/sys/auxv/linux/CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libc/src/sys/auxv/linux/CMakeLists.txt b/libc/src/sys/auxv/linux/CMakeLists.txt
index ab6f01a314f0e..d21754874830d 100644
--- a/libc/src/sys/auxv/linux/CMakeLists.txt
+++ b/libc/src/sys/auxv/linux/CMakeLists.txt
@@ -15,4 +15,4 @@ add_entrypoint_object(
     libc.src.unistd.read
     libc.src.unistd.close
     libc.include.sys_auxv
-)
\ No newline at end of file
+)

>From 11f29fe1309e8e2c8132c27f7a3383eec0b03a9a Mon Sep 17 00:00:00 2001
From: Uzair Nawaz <uzairnawaz at google.com>
Date: Mon, 16 Jun 2025 23:05:52 +0000
Subject: [PATCH 09/11] format fix

---
 libc/src/__support/OSUtil/linux/prctl.cpp | 2 +-
 libc/src/__support/OSUtil/mmap.h          | 5 +++--
 libc/src/__support/OSUtil/read.h          | 2 +-
 libc/src/unistd/linux/read.cpp            | 2 +-
 4 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/libc/src/__support/OSUtil/linux/prctl.cpp b/libc/src/__support/OSUtil/linux/prctl.cpp
index 9f5f2d719c7f4..42370ed4d4abb 100644
--- a/libc/src/__support/OSUtil/linux/prctl.cpp
+++ b/libc/src/__support/OSUtil/linux/prctl.cpp
@@ -18,7 +18,7 @@ namespace LIBC_NAMESPACE_DECL {
 namespace internal {
 
 ErrorOr<int> prctl(int option, unsigned long arg2, unsigned long arg3,
-          unsigned long arg4, unsigned long arg5) {
+                   unsigned long arg4, unsigned long arg5) {
   long ret =
       LIBC_NAMESPACE::syscall_impl(SYS_prctl, option, arg2, arg3, arg4, arg5);
 
diff --git a/libc/src/__support/OSUtil/mmap.h b/libc/src/__support/OSUtil/mmap.h
index 6d91bd5477f95..891c52593362e 100644
--- a/libc/src/__support/OSUtil/mmap.h
+++ b/libc/src/__support/OSUtil/mmap.h
@@ -9,14 +9,15 @@
 #ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_MMAP_H
 #define LLVM_LIBC_SRC___SUPPORT_OSUTIL_MMAP_H
 
-#include "src/__support/macros/config.h"
 #include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
 #include <sys/mman.h> // For size_t and off_t
 
 namespace LIBC_NAMESPACE_DECL {
 namespace internal {
 
-ErrorOr<void*> mmap(void *addr, size_t size, int prot, int flags, int fd, off_t offset);
+ErrorOr<void *> mmap(void *addr, size_t size, int prot, int flags, int fd,
+                     off_t offset);
 
 } // namespace internal
 } // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/__support/OSUtil/read.h b/libc/src/__support/OSUtil/read.h
index 0e29fc36cfa24..16406e432a53b 100644
--- a/libc/src/__support/OSUtil/read.h
+++ b/libc/src/__support/OSUtil/read.h
@@ -12,8 +12,8 @@
 #include "hdr/types/size_t.h"
 #include "hdr/types/ssize_t.h"
 #include "hdr/unistd_macros.h"
-#include "src/__support/macros/config.h"
 #include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
 
 namespace LIBC_NAMESPACE_DECL {
 namespace internal {
diff --git a/libc/src/unistd/linux/read.cpp b/libc/src/unistd/linux/read.cpp
index 2f8a991e5558c..79a78cdd714d7 100644
--- a/libc/src/unistd/linux/read.cpp
+++ b/libc/src/unistd/linux/read.cpp
@@ -9,8 +9,8 @@
 #include "src/unistd/read.h"
 
 #include "src/__support/OSUtil/read.h" // For internal syscall function.
-#include "src/__support/libc_errno.h"
 #include "src/__support/common.h"
+#include "src/__support/libc_errno.h"
 
 namespace LIBC_NAMESPACE_DECL {
 

>From cab7ffe167249d5aad0d68b72509761594f03482 Mon Sep 17 00:00:00 2001
From: Uzair Nawaz <uzairnawaz at google.com>
Date: Mon, 16 Jun 2025 23:27:32 +0000
Subject: [PATCH 10/11] use proxy headers for size_t/ssize_t

---
 libc/src/__support/OSUtil/mmap.h   |  3 ++-
 libc/src/__support/OSUtil/munmap.h |  3 ++-
 libc/src/sys/mman/linux/mmap.cpp   | 11 ++++++-----
 3 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/libc/src/__support/OSUtil/mmap.h b/libc/src/__support/OSUtil/mmap.h
index 891c52593362e..b884d0ece5ab4 100644
--- a/libc/src/__support/OSUtil/mmap.h
+++ b/libc/src/__support/OSUtil/mmap.h
@@ -9,9 +9,10 @@
 #ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_MMAP_H
 #define LLVM_LIBC_SRC___SUPPORT_OSUTIL_MMAP_H
 
+#include "hdr/types/off_t.h"
+#include "hdr/types/size_t.h"
 #include "src/__support/error_or.h"
 #include "src/__support/macros/config.h"
-#include <sys/mman.h> // For size_t and off_t
 
 namespace LIBC_NAMESPACE_DECL {
 namespace internal {
diff --git a/libc/src/__support/OSUtil/munmap.h b/libc/src/__support/OSUtil/munmap.h
index 5e1a961f4d654..ed75c8178dfa1 100644
--- a/libc/src/__support/OSUtil/munmap.h
+++ b/libc/src/__support/OSUtil/munmap.h
@@ -9,9 +9,10 @@
 #ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_MUNMAP_H
 #define LLVM_LIBC_SRC___SUPPORT_OSUTIL_MUNMAP_H
 
+#include "hdr/types/off_t.h"
+#include "hdr/types/size_t.h"
 #include "src/__support/error_or.h"
 #include "src/__support/macros/config.h"
-#include <sys/mman.h> // For size_t and off_t
 
 namespace LIBC_NAMESPACE_DECL {
 namespace internal {
diff --git a/libc/src/sys/mman/linux/mmap.cpp b/libc/src/sys/mman/linux/mmap.cpp
index e149a787fd67b..27df12719e096 100644
--- a/libc/src/sys/mman/linux/mmap.cpp
+++ b/libc/src/sys/mman/linux/mmap.cpp
@@ -19,11 +19,12 @@ LLVM_LIBC_FUNCTION(void *, mmap,
                     off_t offset)) {
   auto ptr = internal::mmap(addr, size, prot, flags, fd, offset);
 
-  if (ptr.has_value())
-    return ptr.value();
-
-  libc_errno = ptr.error();
-  return MAP_FAILED;
+  if (!ptr.has_value()) {
+    libc_errno = ptr.error();
+    return MAP_FAILED;
+  }
+  
+  return ptr.value();
 }
 
 } // namespace LIBC_NAMESPACE_DECL

>From d68d0f90d20ddf5dd21741dbe0e18c5d8a8d27d9 Mon Sep 17 00:00:00 2001
From: Uzair Nawaz <uzairnawaz at google.com>
Date: Tue, 17 Jun 2025 20:29:50 +0000
Subject: [PATCH 11/11] added LIBC_UNLIKELY to optimize for non-error cases

---
 libc/src/__support/OSUtil/linux/mmap.cpp   | 3 ++-
 libc/src/__support/OSUtil/linux/munmap.cpp | 5 +++--
 libc/src/__support/OSUtil/linux/prctl.cpp  | 3 ++-
 libc/src/__support/OSUtil/linux/read.cpp   | 7 ++++---
 libc/src/sys/mman/linux/mmap.cpp           | 5 +++--
 libc/src/sys/mman/linux/munmap.cpp         | 3 ++-
 6 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/libc/src/__support/OSUtil/linux/mmap.cpp b/libc/src/__support/OSUtil/linux/mmap.cpp
index 9e27701e73572..05dc79c4662ab 100644
--- a/libc/src/__support/OSUtil/linux/mmap.cpp
+++ b/libc/src/__support/OSUtil/linux/mmap.cpp
@@ -14,6 +14,7 @@
 #include "src/__support/macros/config.h"
 #include <linux/param.h> // For EXEC_PAGESIZE.
 #include <sys/syscall.h> // For syscall numbers.
+#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
 
 namespace LIBC_NAMESPACE_DECL {
 namespace internal {
@@ -55,7 +56,7 @@ ErrorOr<void *> mmap(void *addr, size_t size, int prot, int flags, int fd,
   // 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 (LIBC_UNLIKELY(ret < 0 && ret > -EXEC_PAGESIZE))
     return Error(static_cast<int>(-ret));
 
   return reinterpret_cast<void *>(ret);
diff --git a/libc/src/__support/OSUtil/linux/munmap.cpp b/libc/src/__support/OSUtil/linux/munmap.cpp
index 6a11bae263f13..0c42a65a96c2f 100644
--- a/libc/src/__support/OSUtil/linux/munmap.cpp
+++ b/libc/src/__support/OSUtil/linux/munmap.cpp
@@ -13,7 +13,8 @@
 
 #include "src/__support/error_or.h"
 #include "src/__support/macros/config.h"
-#include <sys/syscall.h> // For syscall numbers.
+#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
+#include <sys/syscall.h>                       // For syscall numbers.
 
 namespace LIBC_NAMESPACE_DECL {
 namespace internal {
@@ -24,7 +25,7 @@ ErrorOr<int> munmap(void *addr, size_t size) {
   int ret = LIBC_NAMESPACE::syscall_impl<int>(
       SYS_munmap, reinterpret_cast<long>(addr), size);
 
-  if (ret < 0)
+  if (LIBC_UNLIKELY(ret < 0))
     return Error(-ret);
 
   return 0;
diff --git a/libc/src/__support/OSUtil/linux/prctl.cpp b/libc/src/__support/OSUtil/linux/prctl.cpp
index 42370ed4d4abb..e701b531ca6fe 100644
--- a/libc/src/__support/OSUtil/linux/prctl.cpp
+++ b/libc/src/__support/OSUtil/linux/prctl.cpp
@@ -12,6 +12,7 @@
 
 #include "src/__support/error_or.h"
 #include "src/__support/macros/config.h"
+#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
 #include <sys/syscall.h> // For syscall numbers.
 
 namespace LIBC_NAMESPACE_DECL {
@@ -29,7 +30,7 @@ ErrorOr<int> prctl(int option, unsigned long arg2, unsigned long arg3,
   // (https://github.com/torvalds/linux/blob/bee0e7762ad2c6025b9f5245c040fcc36ef2bde8/kernel/sys.c#L2442),
   // return value from the syscall is set to 0 on default so we do not need to
   // set the value on success manually.
-  if (ret < 0)
+  if (LIBC_UNLIKELY(ret < 0))
     return Error(static_cast<int>(-ret));
 
   return static_cast<int>(ret);
diff --git a/libc/src/__support/OSUtil/linux/read.cpp b/libc/src/__support/OSUtil/linux/read.cpp
index 88b6c9c754f68..23d7597da3740 100644
--- a/libc/src/__support/OSUtil/linux/read.cpp
+++ b/libc/src/__support/OSUtil/linux/read.cpp
@@ -11,15 +11,16 @@
 #include "src/__support/OSUtil/syscall.h" // For internal syscall function.
 #include "src/__support/common.h"
 #include "src/__support/macros/config.h"
-#include "src/__support/macros/sanitizer.h" // for MSAN_UNPOISON
-#include <sys/syscall.h>                    // For syscall numbers.
+#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
+#include "src/__support/macros/sanitizer.h"    // for MSAN_UNPOISON
+#include <sys/syscall.h>                       // For syscall numbers.
 
 namespace LIBC_NAMESPACE_DECL {
 namespace internal {
 
 ErrorOr<ssize_t> read(int fd, void *buf, size_t count) {
   ssize_t ret = LIBC_NAMESPACE::syscall_impl<ssize_t>(SYS_read, fd, buf, count);
-  if (ret < 0)
+  if (LIBC_UNLIKELY(ret < 0))
     return Error(static_cast<int>(-ret));
 
   // The cast is important since there is a check that dereferences the pointer
diff --git a/libc/src/sys/mman/linux/mmap.cpp b/libc/src/sys/mman/linux/mmap.cpp
index 27df12719e096..a0cb726132ed2 100644
--- a/libc/src/sys/mman/linux/mmap.cpp
+++ b/libc/src/sys/mman/linux/mmap.cpp
@@ -11,6 +11,7 @@
 #include "src/__support/OSUtil/mmap.h"
 #include "src/__support/common.h"
 #include "src/__support/libc_errno.h"
+#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
 
 namespace LIBC_NAMESPACE_DECL {
 
@@ -19,11 +20,11 @@ LLVM_LIBC_FUNCTION(void *, mmap,
                     off_t offset)) {
   auto ptr = internal::mmap(addr, size, prot, flags, fd, offset);
 
-  if (!ptr.has_value()) {
+  if (LIBC_UNLIKELY(!ptr.has_value())) {
     libc_errno = ptr.error();
     return MAP_FAILED;
   }
-  
+
   return ptr.value();
 }
 
diff --git a/libc/src/sys/mman/linux/munmap.cpp b/libc/src/sys/mman/linux/munmap.cpp
index 34bbca3231f9c..d4613b5899503 100644
--- a/libc/src/sys/mman/linux/munmap.cpp
+++ b/libc/src/sys/mman/linux/munmap.cpp
@@ -11,6 +11,7 @@
 #include "src/__support/OSUtil/munmap.h"
 #include "src/__support/common.h"
 #include "src/__support/libc_errno.h"
+#include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
 
 namespace LIBC_NAMESPACE_DECL {
 
@@ -19,7 +20,7 @@ LLVM_LIBC_FUNCTION(int, munmap, (void *addr, size_t size)) {
 
   // A negative return value indicates an error with the magnitude of the
   // value being the error code.
-  if (!ret.has_value()) {
+  if (LIBC_UNLIKELY(!ret.has_value())) {
     libc_errno = ret.error();
     return -1;
   }



More information about the libc-commits mailing list