Skip to content

[libc] implement prctl #74386

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Dec 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions libc/config/linux/aarch64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,9 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.sys.wait.wait4
libc.src.sys.wait.waitpid

# sys/prctl.h entrypoints
libc.src.sys.prctl.prctl

# termios.h entrypoints
libc.src.termios.cfgetispeed
libc.src.termios.cfgetospeed
Expand Down
3 changes: 3 additions & 0 deletions libc/config/linux/arm/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ set(TARGET_LIBC_ENTRYPOINTS
# sys/mman.h entrypoints
libc.src.sys.mman.mmap
libc.src.sys.mman.munmap

# sys/prctl.h entrypoints
libc.src.sys.prctl.prctl
)

set(TARGET_LIBM_ENTRYPOINTS
Expand Down
3 changes: 3 additions & 0 deletions libc/config/linux/riscv/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.sys.wait.wait4
libc.src.sys.wait.waitpid

# sys/prctl.h entrypoints
libc.src.sys.prctl.prctl

# termios.h entrypoints
libc.src.termios.cfgetispeed
libc.src.termios.cfgetospeed
Expand Down
3 changes: 3 additions & 0 deletions libc/config/linux/x86_64/entrypoints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,9 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.sys.wait.wait4
libc.src.sys.wait.waitpid

# sys/prctl.h entrypoints
libc.src.sys.prctl.prctl

# termios.h entrypoints
libc.src.termios.cfgetispeed
libc.src.termios.cfgetospeed
Expand Down
2 changes: 0 additions & 2 deletions libc/include/sys/prctl.h.def
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
// the macros itself.
#include <linux/prctl.h>

// TODO: Define the prctl macros.

%%public_api()

#endif // LLVM_LIBC_SYS_PRCTL_H
1 change: 1 addition & 0 deletions libc/src/sys/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ add_subdirectory(sendfile)
add_subdirectory(stat)
add_subdirectory(utsname)
add_subdirectory(wait)
add_subdirectory(prctl)
10 changes: 10 additions & 0 deletions libc/src/sys/prctl/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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(
prctl
ALIAS
DEPENDS
.${LIBC_TARGET_OS}.prctl
)
12 changes: 12 additions & 0 deletions libc/src/sys/prctl/linux/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
add_entrypoint_object(
prctl
SRCS
prctl.cpp
HDRS
../prctl.h
DEPENDS
libc.include.sys_prctl
libc.include.sys_syscall
libc.src.__support.OSUtil.osutil
libc.src.errno.errno
)
37 changes: 37 additions & 0 deletions libc/src/sys/prctl/linux/prctl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//===---------- Linux implementation of the prctl 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/prctl/prctl.h"

#include "src/__support/OSUtil/syscall.h" // For internal syscall function.

#include "src/errno/libc_errno.h"
#include <sys/syscall.h> // For syscall numbers.

namespace LIBC_NAMESPACE {

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);
return -1;
}
return static_cast<int>(ret);
}

} // namespace LIBC_NAMESPACE
21 changes: 21 additions & 0 deletions libc/src/sys/prctl/prctl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//===-- Implementation header for prctl ---------------------------*-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_PRCTL_PRCTL_H
#define LLVM_LIBC_SRC_SYS_PRCTL_PRCTL_H

#include <sys/prctl.h>

namespace LIBC_NAMESPACE {

int prctl(int option, unsigned long arg2, unsigned long arg3,
unsigned long arg4, unsigned long arg5);

} // namespace LIBC_NAMESPACE

#endif // LLVM_LIBC_SRC_SYS_PRCTL_PRCTL_H
1 change: 1 addition & 0 deletions libc/test/src/sys/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ add_subdirectory(socket)
add_subdirectory(stat)
add_subdirectory(utsname)
add_subdirectory(wait)
add_subdirectory(prctl)
3 changes: 3 additions & 0 deletions libc/test/src/sys/prctl/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
add_subdirectory(${LIBC_TARGET_OS})
endif()
14 changes: 14 additions & 0 deletions libc/test/src/sys/prctl/linux/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
add_custom_target(libc_sys_prctl_unittests)

add_libc_unittest(
prctl_test
SUITE
libc_sys_prctl_unittests
SRCS
prctl_test.cpp
DEPENDS
libc.include.sys_prctl
libc.include.errno
libc.src.sys.prctl.prctl
libc.src.errno.errno
)
44 changes: 44 additions & 0 deletions libc/test/src/sys/prctl/linux/prctl_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//===-- Unittests for prctl -----------------------------------------------===//
//
// 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/errno/libc_errno.h"
#include "src/sys/prctl/prctl.h"
#include "test/UnitTest/ErrnoSetterMatcher.h"
#include <errno.h>
#include <sys/prctl.h>

using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails;
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;

TEST(LlvmLibcSysPrctlTest, GetSetName) {
char name[17];
unsigned long name_addr = 0;
ASSERT_THAT(LIBC_NAMESPACE::prctl(PR_GET_NAME, name_addr, 0, 0, 0),
Fails(EFAULT, -1));

name_addr = reinterpret_cast<unsigned long>("libc-test");
ASSERT_THAT(LIBC_NAMESPACE::prctl(PR_SET_NAME, name_addr, 0, 0, 0),
Succeeds());

name_addr = reinterpret_cast<unsigned long>(name);
ASSERT_THAT(LIBC_NAMESPACE::prctl(PR_GET_NAME, name_addr, 0, 0, 0),
Succeeds());
ASSERT_STREQ(name, "libc-test");
}

TEST(LlvmLibcSysPrctlTest, GetTHPDisable) {
// Manually check errno since the return value logic here is not
// covered in ErrnoSetterMatcher.
libc_errno = 0;
int ret = LIBC_NAMESPACE::prctl(PR_GET_THP_DISABLE, 0, 0, 0, 0);
ASSERT_EQ(libc_errno, 0);
// PR_GET_THP_DISABLE return (as the function result) the current
// setting of the "THP disable" flag for the calling thread, which
// is either 1, if the flag is set; or 0, if it is not.
ASSERT_TRUE(ret == 0 || ret == 1);
}