diff --git a/libc/config/linux/api.td b/libc/config/linux/api.td --- a/libc/config/linux/api.td +++ b/libc/config/linux/api.td @@ -209,7 +209,7 @@ } def SysResourceAPI : PublicAPI<"sys/resource.h"> { - let Types = ["rlim_t", "struct rlimit"]; + let Types = ["rlim_t", "struct rlimit", "rlim64_t", "struct rlimit64"]; } def SysStatAPI : PublicAPI<"sys/stat.h"> { diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt --- a/libc/include/CMakeLists.txt +++ b/libc/include/CMakeLists.txt @@ -340,6 +340,8 @@ .llvm-libc-macros.sys_resource_macros .llvm-libc-types.rlim_t .llvm-libc-types.struct_rlimit + .llvm-libc-types.rlim64_t + .llvm-libc-types.struct_rlimit64 ) add_gen_header( diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt --- a/libc/include/llvm-libc-types/CMakeLists.txt +++ b/libc/include/llvm-libc-types/CMakeLists.txt @@ -54,11 +54,13 @@ add_header(pthread_mutexattr_t HDR pthread_mutexattr_t.h) add_header(pthread_once_t HDR pthread_once_t.h DEPENDS .__futex_word) add_header(rlim_t HDR rlim_t.h) +add_header(rlim64_t HDR rlim64_t.h) add_header(time_t HDR time_t.h) add_header(stack_t HDR stack_t.h) add_header(suseconds_t HDR suseconds_t.h) add_header(struct_timeval HDR struct_timeval.h DEPENDS .suseconds_t .time_t) add_header(struct_rlimit HDR struct_rlimit.h DEPENDS .rlim_t) +add_header(struct_rlimit64 HDR struct_rlimit64.h DEPENDS .rlim64_t) add_header(struct_rusage HDR struct_rusage.h DEPENDS .struct_timeval) add_header(struct_dirent HDR struct_dirent.h DEPENDS .ino_t .off_t) add_header(struct_sched_param HDR struct_sched_param.h) diff --git a/libc/include/llvm-libc-types/rlim64_t.h b/libc/include/llvm-libc-types/rlim64_t.h new file mode 100644 --- /dev/null +++ b/libc/include/llvm-libc-types/rlim64_t.h @@ -0,0 +1,14 @@ +//===-- Definition of type rlim64_t ---------------------------------------===// +// +// 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_TYPES_RLIM64_T_H__ +#define __LLVM_LIBC_TYPES_RLIM64_T_H__ + +typedef __UINT64_TYPE__ rlim64_t; + +#endif // __LLVM_LIBC_TYPES_RLIM64_T_H__ diff --git a/libc/include/llvm-libc-types/struct_rlimit64.h b/libc/include/llvm-libc-types/struct_rlimit64.h new file mode 100644 --- /dev/null +++ b/libc/include/llvm-libc-types/struct_rlimit64.h @@ -0,0 +1,19 @@ +//===-- Definition of type struct rlimit64 --------------------------------===// +// +// 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_TYPES_STRUCT_RLIMIT64_H__ +#define __LLVM_LIBC_TYPES_STRUCT_RLIMIT64_H__ + +#include + +struct rlimit64 { + rlim64_t rlim_cur; + rlim64_t rlim_max; +}; + +#endif // __LLVM_LIBC_TYPES_STRUCT_RLIMIT64_H__ diff --git a/libc/spec/posix.td b/libc/spec/posix.td --- a/libc/spec/posix.td +++ b/libc/spec/posix.td @@ -767,12 +767,14 @@ NamedType RLimTType = NamedType<"rlim_t">; NamedType StructRLimitType = NamedType<"struct rlimit">; + NamedType RLim64TType = NamedType<"rlim64_t">; + NamedType StructRLimit64Type = NamedType<"struct rlimit64">; PtrType StructRLimitPtr = PtrType; ConstType ConstStructRLimitPtr = ConstType; HeaderSpec SysResource = HeaderSpec< "sys/resource.h", [], // Macros - [RLimTType, StructRLimitType], // Types + [RLimTType, StructRLimitType, RLim64TType, StructRLimit64Type], // Types [], // Enumerations [ FunctionSpec< diff --git a/libc/src/sys/resource/linux/getrlimit.cpp b/libc/src/sys/resource/linux/getrlimit.cpp --- a/libc/src/sys/resource/linux/getrlimit.cpp +++ b/libc/src/sys/resource/linux/getrlimit.cpp @@ -18,12 +18,26 @@ namespace __llvm_libc { LLVM_LIBC_FUNCTION(int, getrlimit, (int res, struct rlimit *limits)) { +#if defined(LIBC_TARGET_ARCH_IS_RISCV32) || defined(LIBC_TARGET_ARCH_IS_ARM32) + // SYS_prlimit64 takes a rlimit64 struct, which is a struct rlimit with + // 64-bit members. In 32-bit systems struct rlimit has 32-bit members, so + // we need to fill a rlimit64 struct with the 32-bit values from struct rlimit + struct rlimit64 lim; +#else + struct rlimit lim; +#endif + lim.rlim_cur = limits->rlim_cur; + lim.rlim_max = limits->rlim_max; + int ret = - __llvm_libc::syscall_impl(SYS_prlimit64, 0, res, nullptr, limits); + __llvm_libc::syscall_impl(SYS_prlimit64, 0, res, nullptr, &lim); if (ret < 0) { libc_errno = -ret; return -1; } + + limits->rlim_cur = static_cast(lim.rlim_cur); + limits->rlim_max = static_cast(lim.rlim_max); return 0; } diff --git a/libc/src/sys/resource/linux/setrlimit.cpp b/libc/src/sys/resource/linux/setrlimit.cpp --- a/libc/src/sys/resource/linux/setrlimit.cpp +++ b/libc/src/sys/resource/linux/setrlimit.cpp @@ -18,8 +18,19 @@ namespace __llvm_libc { LLVM_LIBC_FUNCTION(int, setrlimit, (int res, const struct rlimit *limits)) { +#if defined(LIBC_TARGET_ARCH_IS_RISCV32) || defined(LIBC_TARGET_ARCH_IS_ARM32) + // SYS_prlimit64 takes a rlimit64 struct, which is a struct rlimit with + // 64-bit members. In 32-bit systems struct rlimit has 32-bit members, so + // we need to fill a rlimit64 struct with the 32-bit values from struct rlimit + struct rlimit64 lim; +#else + struct rlimit lim; +#endif + lim.rlim_cur = limits->rlim_cur; + lim.rlim_max = limits->rlim_max; + int ret = - __llvm_libc::syscall_impl(SYS_prlimit64, 0, res, limits, nullptr); + __llvm_libc::syscall_impl(SYS_prlimit64, 0, res, &lim, nullptr); if (ret < 0) { libc_errno = -ret; return -1;