[libc-commits] [libc] [libc] Implement sys/personality.h (PR #195065)

via libc-commits libc-commits at lists.llvm.org
Thu Apr 30 05:49:01 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libc

Author: Jeff Bailey (kaladron)

<details>
<summary>Changes</summary>

Added the personality() syscall wrapper, which sets or queries the process execution domain. The function signature follows the Linux man page: int personality(unsigned long persona).

New files:
* libc/include/sys/personality.{yaml,h.def}
* libc/src/sys/personality/ (implementation + linux/ syscall)
* libc/test/src/sys/personality/ (unit tests)

Registered the entrypoint and header for x86_64, aarch64, riscv, and arm. The implementation includes <linux/personality.h> for the kernel-defined constants (PER_LINUX, ADDR_NO_RANDOMIZE, etc.) following the same pattern as sys/prctl.h.

---
Full diff: https://github.com/llvm/llvm-project/pull/195065.diff


22 Files Affected:

- (modified) libc/config/linux/aarch64/entrypoints.txt (+3) 
- (modified) libc/config/linux/aarch64/headers.txt (+1) 
- (modified) libc/config/linux/arm/entrypoints.txt (+3) 
- (modified) libc/config/linux/arm/headers.txt (+2) 
- (modified) libc/config/linux/riscv/entrypoints.txt (+3) 
- (modified) libc/config/linux/riscv/headers.txt (+1) 
- (modified) libc/config/linux/x86_64/entrypoints.txt (+3) 
- (modified) libc/config/linux/x86_64/headers.txt (+1) 
- (modified) libc/include/CMakeLists.txt (+8) 
- (added) libc/include/sys/personality.h.def (+19) 
- (added) libc/include/sys/personality.yaml (+13) 
- (modified) libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt (+12) 
- (added) libc/src/__support/OSUtil/linux/syscall_wrappers/personality.h (+31) 
- (modified) libc/src/sys/CMakeLists.txt (+1) 
- (added) libc/src/sys/personality/CMakeLists.txt (+10) 
- (added) libc/src/sys/personality/linux/CMakeLists.txt (+13) 
- (added) libc/src/sys/personality/linux/personality.cpp (+28) 
- (added) libc/src/sys/personality/personality.h (+21) 
- (modified) libc/test/src/sys/CMakeLists.txt (+1) 
- (added) libc/test/src/sys/personality/CMakeLists.txt (+3) 
- (added) libc/test/src/sys/personality/linux/CMakeLists.txt (+15) 
- (added) libc/test/src/sys/personality/linux/personality_test.cpp (+40) 


``````````diff
diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt
index b15edc5e3e102..8f05bd6916e37 100644
--- a/libc/config/linux/aarch64/entrypoints.txt
+++ b/libc/config/linux/aarch64/entrypoints.txt
@@ -307,6 +307,9 @@ set(TARGET_LIBC_ENTRYPOINTS
     # sys/prctl.h entrypoints
     libc.src.sys.prctl.prctl
 
+    # sys/personality.h entrypoints
+    libc.src.sys.personality.personality
+
     # sys/auxv.h entrypoints
     libc.src.sys.auxv.getauxval
 
diff --git a/libc/config/linux/aarch64/headers.txt b/libc/config/linux/aarch64/headers.txt
index 4784fc5d29ddc..05cd13b1980e7 100644
--- a/libc/config/linux/aarch64/headers.txt
+++ b/libc/config/linux/aarch64/headers.txt
@@ -39,6 +39,7 @@ set(TARGET_PUBLIC_HEADERS
     libc.include.sys_epoll
     libc.include.sys_ioctl
     libc.include.sys_mman
+    libc.include.sys_personality
     libc.include.sys_prctl
     libc.include.sys_queue
     libc.include.sys_random
diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt
index 8a4d88b5ba98c..1c4dd1a4cb879 100644
--- a/libc/config/linux/arm/entrypoints.txt
+++ b/libc/config/linux/arm/entrypoints.txt
@@ -183,6 +183,9 @@ set(TARGET_LIBC_ENTRYPOINTS
     # sys/prctl.h entrypoints
     libc.src.sys.prctl.prctl
 
+    # sys/personality.h entrypoints
+    libc.src.sys.personality.personality
+
     # sys/epoll.h entrypoints
     # Disabled due to epoll_wait syscalls not being available on this platform.
     # libc.src.sys.epoll.epoll_wait
diff --git a/libc/config/linux/arm/headers.txt b/libc/config/linux/arm/headers.txt
index dad65234363b3..a9c4de1cf790a 100644
--- a/libc/config/linux/arm/headers.txt
+++ b/libc/config/linux/arm/headers.txt
@@ -20,6 +20,8 @@ set(TARGET_PUBLIC_HEADERS
     libc.include.wchar
     libc.include.wctype
 
+    libc.include.sys_personality
+
     # Disabled due to epoll_wait syscalls not being available on this platform.
     # libc.include.sys_epoll
 )
diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt
index 6478aed3b0391..03b2f310d49cc 100644
--- a/libc/config/linux/riscv/entrypoints.txt
+++ b/libc/config/linux/riscv/entrypoints.txt
@@ -310,6 +310,9 @@ set(TARGET_LIBC_ENTRYPOINTS
     # sys/prctl.h entrypoints
     libc.src.sys.prctl.prctl
 
+    # sys/personality.h entrypoints
+    libc.src.sys.personality.personality
+
     # sys/auxv.h entrypoints
     libc.src.sys.auxv.getauxval
 
diff --git a/libc/config/linux/riscv/headers.txt b/libc/config/linux/riscv/headers.txt
index 45c42eb65527c..218b7f8153309 100644
--- a/libc/config/linux/riscv/headers.txt
+++ b/libc/config/linux/riscv/headers.txt
@@ -39,6 +39,7 @@ set(TARGET_PUBLIC_HEADERS
     libc.include.sys_epoll
     libc.include.sys_ioctl
     libc.include.sys_mman
+    libc.include.sys_personality
     libc.include.sys_prctl
     libc.include.sys_queue
     libc.include.sys_random
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index d1c1d9496af67..3ac32de6949c7 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -326,6 +326,9 @@ set(TARGET_LIBC_ENTRYPOINTS
     # sys/prctl.h entrypoints
     libc.src.sys.prctl.prctl
 
+    # sys/personality.h entrypoints
+    libc.src.sys.personality.personality
+
     # sys/auxv.h entrypoints
     libc.src.sys.auxv.getauxval
 
diff --git a/libc/config/linux/x86_64/headers.txt b/libc/config/linux/x86_64/headers.txt
index fb461444b43d8..8c25137bd9de4 100644
--- a/libc/config/linux/x86_64/headers.txt
+++ b/libc/config/linux/x86_64/headers.txt
@@ -41,6 +41,7 @@ set(TARGET_PUBLIC_HEADERS
     libc.include.sys_ioctl
     libc.include.sys_ipc
     libc.include.sys_mman
+    libc.include.sys_personality
     libc.include.sys_prctl
     libc.include.sys_queue
     libc.include.sys_random
diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index 79380c5a21cd6..bca9aa68be76d 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -639,6 +639,14 @@ add_header_macro(
     .llvm-libc-types.ssize_t
 )
 
+add_header_macro(
+  sys_personality
+  ../libc/include/sys/personality.yaml
+  sys/personality.h
+  DEPENDS
+    .llvm_libc_common_h
+)
+
 add_header_macro(
   sys_prctl
   ../libc/include/sys/prctl.yaml
diff --git a/libc/include/sys/personality.h.def b/libc/include/sys/personality.h.def
new file mode 100644
index 0000000000000..15007dbf8c426
--- /dev/null
+++ b/libc/include/sys/personality.h.def
@@ -0,0 +1,19 @@
+//===-- Linux header personality.h ----------------------------------------===//
+//
+// 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_SYS_PERSONALITY_H
+#define LLVM_LIBC_SYS_PERSONALITY_H
+
+#include "__llvm-libc-common.h"
+
+// The personality constants and flags are defined by the kernel.
+#include <linux/personality.h>
+
+%%public_api()
+
+#endif // LLVM_LIBC_SYS_PERSONALITY_H
diff --git a/libc/include/sys/personality.yaml b/libc/include/sys/personality.yaml
new file mode 100644
index 0000000000000..33fb51caa64f2
--- /dev/null
+++ b/libc/include/sys/personality.yaml
@@ -0,0 +1,13 @@
+header: sys/personality.h
+header_template: personality.h.def
+macros: []
+types: []
+enums: []
+objects: []
+functions:
+  - name: personality
+    standards:
+      - Linux
+    return_type: int
+    arguments:
+      - type: unsigned long
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
index 049eeac913780..0417456a31ce6 100644
--- a/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt
@@ -159,6 +159,18 @@ add_header_library(
     libc.include.sys_syscall
 )
 
+add_header_library(
+  personality
+  HDRS
+    personality.h
+  DEPENDS
+    libc.src.__support.OSUtil.osutil
+    libc.src.__support.common
+    libc.src.__support.error_or
+    libc.src.__support.macros.config
+    libc.include.sys_syscall
+)
+
 add_header_library(
   utimensat
   HDRS
diff --git a/libc/src/__support/OSUtil/linux/syscall_wrappers/personality.h b/libc/src/__support/OSUtil/linux/syscall_wrappers/personality.h
new file mode 100644
index 0000000000000..163c1c4113c9d
--- /dev/null
+++ b/libc/src/__support/OSUtil/linux/syscall_wrappers/personality.h
@@ -0,0 +1,31 @@
+//===-- Syscall wrapper for personality -------------------------*- 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_SYSCALL_WRAPPERS_PERSONALITY_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_PERSONALITY_H
+
+#include "src/__support/OSUtil/linux/syscall.h" // syscall_impl
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<int> personality(unsigned long persona) {
+  long ret = syscall_impl<long>(SYS_personality, persona);
+  if (ret < 0)
+    return Error(-static_cast<int>(ret));
+  return static_cast<int>(ret);
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_PERSONALITY_H
diff --git a/libc/src/sys/CMakeLists.txt b/libc/src/sys/CMakeLists.txt
index 41becce798ddd..585b8f7b158eb 100644
--- a/libc/src/sys/CMakeLists.txt
+++ b/libc/src/sys/CMakeLists.txt
@@ -2,6 +2,7 @@ add_subdirectory(auxv)
 add_subdirectory(epoll)
 add_subdirectory(ipc)
 add_subdirectory(mman)
+add_subdirectory(personality)
 add_subdirectory(random)
 add_subdirectory(resource)
 add_subdirectory(select)
diff --git a/libc/src/sys/personality/CMakeLists.txt b/libc/src/sys/personality/CMakeLists.txt
new file mode 100644
index 0000000000000..d2f655305e64f
--- /dev/null
+++ b/libc/src/sys/personality/CMakeLists.txt
@@ -0,0 +1,10 @@
+if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
+  add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
+endif()
+
+add_entrypoint_object(
+  personality
+  ALIAS
+  DEPENDS
+    .${LIBC_TARGET_OS}.personality
+)
diff --git a/libc/src/sys/personality/linux/CMakeLists.txt b/libc/src/sys/personality/linux/CMakeLists.txt
new file mode 100644
index 0000000000000..b7aff12947632
--- /dev/null
+++ b/libc/src/sys/personality/linux/CMakeLists.txt
@@ -0,0 +1,13 @@
+add_entrypoint_object(
+  personality
+  SRCS
+    personality.cpp
+  HDRS
+    ../personality.h
+  DEPENDS
+    libc.src.__support.OSUtil.linux.syscall_wrappers.personality
+    libc.src.__support.common
+    libc.src.__support.error_or
+    libc.src.__support.libc_errno
+    libc.src.__support.macros.config
+)
diff --git a/libc/src/sys/personality/linux/personality.cpp b/libc/src/sys/personality/linux/personality.cpp
new file mode 100644
index 0000000000000..c2f97b479f0a5
--- /dev/null
+++ b/libc/src/sys/personality/linux/personality.cpp
@@ -0,0 +1,28 @@
+//===--------- Linux implementation of the personality function -----------===//
+//
+// 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/sys/personality/personality.h"
+
+#include "src/__support/OSUtil/linux/syscall_wrappers/personality.h"
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/libc_errno.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+LLVM_LIBC_FUNCTION(int, personality, (unsigned long persona)) {
+  auto result = linux_syscalls::personality(persona);
+  if (!result.has_value()) {
+    libc_errno = static_cast<int>(result.error());
+    return -1;
+  }
+  return result.value();
+}
+
+} // namespace LIBC_NAMESPACE_DECL
diff --git a/libc/src/sys/personality/personality.h b/libc/src/sys/personality/personality.h
new file mode 100644
index 0000000000000..e5c9ebf9aa9f6
--- /dev/null
+++ b/libc/src/sys/personality/personality.h
@@ -0,0 +1,21 @@
+//===-- Implementation header for personality ---------------------*-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_SYS_PERSONALITY_PERSONALITY_H
+#define LLVM_LIBC_SRC_SYS_PERSONALITY_PERSONALITY_H
+
+#include "src/__support/macros/config.h"
+#include <sys/personality.h>
+
+namespace LIBC_NAMESPACE_DECL {
+
+int personality(unsigned long persona);
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC_SYS_PERSONALITY_PERSONALITY_H
diff --git a/libc/test/src/sys/CMakeLists.txt b/libc/test/src/sys/CMakeLists.txt
index 444f86f5d00a9..9af889bffa46d 100644
--- a/libc/test/src/sys/CMakeLists.txt
+++ b/libc/test/src/sys/CMakeLists.txt
@@ -1,4 +1,5 @@
 add_subdirectory(mman)
+add_subdirectory(personality)
 add_subdirectory(random)
 add_subdirectory(resource)
 add_subdirectory(select)
diff --git a/libc/test/src/sys/personality/CMakeLists.txt b/libc/test/src/sys/personality/CMakeLists.txt
new file mode 100644
index 0000000000000..b4bbe81c92ff2
--- /dev/null
+++ b/libc/test/src/sys/personality/CMakeLists.txt
@@ -0,0 +1,3 @@
+if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
+  add_subdirectory(${LIBC_TARGET_OS})
+endif()
diff --git a/libc/test/src/sys/personality/linux/CMakeLists.txt b/libc/test/src/sys/personality/linux/CMakeLists.txt
new file mode 100644
index 0000000000000..18ab52d33dc65
--- /dev/null
+++ b/libc/test/src/sys/personality/linux/CMakeLists.txt
@@ -0,0 +1,15 @@
+add_custom_target(libc_sys_personality_unittests)
+
+add_libc_unittest(
+  personality_test
+  SUITE
+    libc_sys_personality_unittests
+  SRCS
+    personality_test.cpp
+  DEPENDS
+    libc.include.sys_personality
+    libc.src.sys.personality.personality
+    libc.src.errno.errno
+    libc.test.UnitTest.ErrnoCheckingTest
+    libc.test.UnitTest.ErrnoSetterMatcher
+)
diff --git a/libc/test/src/sys/personality/linux/personality_test.cpp b/libc/test/src/sys/personality/linux/personality_test.cpp
new file mode 100644
index 0000000000000..6fdaa756857b9
--- /dev/null
+++ b/libc/test/src/sys/personality/linux/personality_test.cpp
@@ -0,0 +1,40 @@
+//===-- Unittests for personality -----------------------------------------===//
+//
+// 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/sys/personality/personality.h"
+#include "test/UnitTest/ErrnoCheckingTest.h"
+#include "test/UnitTest/ErrnoSetterMatcher.h"
+#include <sys/personality.h>
+
+using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
+using LlvmLibcSysPersonalityTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
+
+TEST_F(LlvmLibcSysPersonalityTest, GetPersonality) {
+  // Passing 0xffffffff retrieves the current persona without changing it.
+  int persona = LIBC_NAMESPACE::personality(0xffffffff);
+  ASSERT_ERRNO_SUCCESS();
+  ASSERT_GE(persona, 0);
+}
+
+TEST_F(LlvmLibcSysPersonalityTest, SetAndRestore) {
+  // Get the current persona.
+  int original = LIBC_NAMESPACE::personality(0xffffffff);
+  ASSERT_ERRNO_SUCCESS();
+  ASSERT_GE(original, 0);
+
+  // Set the personality to the same value; should succeed and return the
+  // previous persona.
+  int prev = LIBC_NAMESPACE::personality(original);
+  ASSERT_ERRNO_SUCCESS();
+  ASSERT_EQ(prev, original);
+
+  // Verify the personality is unchanged.
+  int current = LIBC_NAMESPACE::personality(0xffffffff);
+  ASSERT_ERRNO_SUCCESS();
+  ASSERT_EQ(current, original);
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/195065


More information about the libc-commits mailing list