[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