[libc-commits] [libc] 9eb1185 - Implement `getrandom` function for linux targets.
Michael Jones via libc-commits
libc-commits at lists.llvm.org
Mon Oct 10 11:00:47 PDT 2022
Author: Schrodinger ZHU Yifan
Date: 2022-10-10T11:00:35-07:00
New Revision: 9eb11856cf1fa62c5408594fafc973eb2d380cdb
URL: https://github.com/llvm/llvm-project/commit/9eb11856cf1fa62c5408594fafc973eb2d380cdb
DIFF: https://github.com/llvm/llvm-project/commit/9eb11856cf1fa62c5408594fafc973eb2d380cdb.diff
LOG: Implement `getrandom` function for linux targets.
Reviewed By: michaelrj, sivachandra
Differential Revision: https://reviews.llvm.org/D134665
Added:
libc/include/llvm-libc-macros/linux/sys-random-macros.h
libc/include/llvm-libc-macros/sys-random-macros.h
libc/include/sys/random.h.def
libc/src/sys/random/CMakeLists.txt
libc/src/sys/random/getrandom.h
libc/src/sys/random/linux/CMakeLists.txt
libc/src/sys/random/linux/getrandom.cpp
libc/test/src/sys/random/CMakeLists.txt
libc/test/src/sys/random/linux/CMakeLists.txt
libc/test/src/sys/random/linux/getrandom_test.cpp
Modified:
libc/config/linux/x86_64/entrypoints.txt
libc/config/linux/x86_64/headers.txt
libc/include/CMakeLists.txt
libc/include/llvm-libc-macros/CMakeLists.txt
libc/include/llvm-libc-macros/linux/CMakeLists.txt
libc/spec/linux.td
libc/src/sys/CMakeLists.txt
libc/test/src/sys/CMakeLists.txt
Removed:
################################################################################
diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt
index 9874cb80d74d6..7e5fde3f27341 100644
--- a/libc/config/linux/x86_64/entrypoints.txt
+++ b/libc/config/linux/x86_64/entrypoints.txt
@@ -113,6 +113,9 @@ set(TARGET_LIBC_ENTRYPOINTS
libc.src.sys.mman.munmap
libc.src.sys.mman.posix_madvise
+ # sys/random.h entrypoints
+ libc.src.sys.random.getrandom
+
# sys/resource.h entrypoints
libc.src.sys.resource.getrlimit
libc.src.sys.resource.setrlimit
diff --git a/libc/config/linux/x86_64/headers.txt b/libc/config/linux/x86_64/headers.txt
index 302d3f8845126..284f964b4ed27 100644
--- a/libc/config/linux/x86_64/headers.txt
+++ b/libc/config/linux/x86_64/headers.txt
@@ -12,6 +12,7 @@ set(TARGET_PUBLIC_HEADERS
libc.include.stdlib
libc.include.string
libc.include.sys_mman
+ libc.include.sys_random
libc.include.sys_syscall
libc.include.threads
libc.include.time
diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index d8b92e2f54735..d30009e7e3fe7 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -228,6 +228,17 @@ add_gen_header(
.llvm-libc-macros.sys_mman_macros
)
+add_gen_header(
+ sys_random
+ DEF_FILE sys/random.h.def
+ GEN_HDR sys/random.h
+ DEPENDS
+ .llvm_libc_common_h
+ .llvm-libc-macros.sys_random_macros
+ .llvm-libc-types.ssize_t
+ .llvm-libc-types.size_t
+)
+
add_gen_header(
sys_resource
DEF_FILE sys/resource.h.def
diff --git a/libc/include/llvm-libc-macros/CMakeLists.txt b/libc/include/llvm-libc-macros/CMakeLists.txt
index dc20602e819c6..def26a13b3a30 100644
--- a/libc/include/llvm-libc-macros/CMakeLists.txt
+++ b/libc/include/llvm-libc-macros/CMakeLists.txt
@@ -52,6 +52,14 @@ add_header(
.linux.sys_mman_macros
)
+add_header(
+ sys_random_macros
+ HDR
+ sys-random-macros.h
+ DEPENDS
+ .linux.sys_random_macros
+)
+
add_header(
sys_resource_macros
HDR
diff --git a/libc/include/llvm-libc-macros/linux/CMakeLists.txt b/libc/include/llvm-libc-macros/linux/CMakeLists.txt
index 8b8e58d341949..e3c9392d34394 100644
--- a/libc/include/llvm-libc-macros/linux/CMakeLists.txt
+++ b/libc/include/llvm-libc-macros/linux/CMakeLists.txt
@@ -17,9 +17,9 @@ add_header(
)
add_header(
- sys_stat_macros
+ sys_random_macros
HDR
- sys-stat-macros.h
+ sys-random-macros.h
)
add_header(
@@ -40,6 +40,12 @@ add_header(
sys-resource-macros.h
)
+add_header(
+ sys_stat_macros
+ HDR
+ sys-stat-macros.h
+)
+
add_header(
unistd_macros
HDR
diff --git a/libc/include/llvm-libc-macros/linux/sys-random-macros.h b/libc/include/llvm-libc-macros/linux/sys-random-macros.h
new file mode 100644
index 0000000000000..1337f8b606fcf
--- /dev/null
+++ b/libc/include/llvm-libc-macros/linux/sys-random-macros.h
@@ -0,0 +1,17 @@
+//===-- Definition of macros from sys/random.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_MACROS_LINUX_SYS_RANDOM_MACROS_H
+#define __LLVM_LIBC_MACROS_LINUX_SYS_RANDOM_MACROS_H
+
+// Getrandom flags
+#define GRND_RANDOM 0x0001
+#define GRND_NONBLOCK 0x0002
+#define GRND_INSECURE 0x0004
+
+#endif // __LLVM_LIBC_MACROS_LINUX_SYS_RANDOM_MACROS_H
diff --git a/libc/include/llvm-libc-macros/sys-random-macros.h b/libc/include/llvm-libc-macros/sys-random-macros.h
new file mode 100644
index 0000000000000..4e59efcaa1597
--- /dev/null
+++ b/libc/include/llvm-libc-macros/sys-random-macros.h
@@ -0,0 +1,16 @@
+//===-- Macros defined in sys/random.h header file ------------------------===//
+//
+// 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_MACROS_SYS_RANDOM_MACROS_H
+#define __LLVM_LIBC_MACROS_SYS_RANDOM_MACROS_H
+
+#ifdef __unix__
+#include "linux/sys-random-macros.h"
+#endif
+
+#endif // __LLVM_LIBC_MACROS_SYS_RANDOM_MACROS_H
diff --git a/libc/include/sys/random.h.def b/libc/include/sys/random.h.def
new file mode 100644
index 0000000000000..b767f2479fc2d
--- /dev/null
+++ b/libc/include/sys/random.h.def
@@ -0,0 +1,18 @@
+//===-- Linux sys/random.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_RANDOM_H
+#define LLVM_LIBC_SYS_RANDOM_H
+
+#include <__llvm-libc-common.h>
+
+#include <llvm-libc-macros/sys-random-macros.h>
+
+%%public_api()
+
+#endif // LLVM_LIBC_SYS_RANDOM_H
diff --git a/libc/spec/linux.td b/libc/spec/linux.td
index 29baf8b1e5ee5..da6ceae66f765 100644
--- a/libc/spec/linux.td
+++ b/libc/spec/linux.td
@@ -63,6 +63,28 @@ def Linux : StandardSpec<"Linux"> {
[Macro<"MAP_ANONYMOUS">]
>;
+ HeaderSpec SysRandom = HeaderSpec<
+ "sys/random.h",
+ [
+ Macro<"GRND_RANDOM">,
+ Macro<"GRND_NONBLOCK">,
+ Macro<"GRND_INSECURE">,
+ ],
+ [], // Types
+ [], // Enumerations
+ [
+ FunctionSpec<
+ "getrandom",
+ RetValSpec<SSizeTType>,
+ [
+ ArgSpec<VoidPtr>,
+ ArgSpec<SizeTType>,
+ ArgSpec<UnsignedIntType>
+ ]
+ >,
+ ]
+ >;
+
HeaderSpec Signal = HeaderSpec<
"signal.h",
[
@@ -108,6 +130,7 @@ def Linux : StandardSpec<"Linux"> {
let Headers = [
Errno,
SysMMan,
+ SysRandom,
Signal,
];
}
diff --git a/libc/src/sys/CMakeLists.txt b/libc/src/sys/CMakeLists.txt
index f8e25cc8d4e54..bf6283df87acb 100644
--- a/libc/src/sys/CMakeLists.txt
+++ b/libc/src/sys/CMakeLists.txt
@@ -1,4 +1,5 @@
add_subdirectory(mman)
+add_subdirectory(random)
add_subdirectory(resource)
add_subdirectory(sendfile)
add_subdirectory(stat)
diff --git a/libc/src/sys/random/CMakeLists.txt b/libc/src/sys/random/CMakeLists.txt
new file mode 100644
index 0000000000000..2291a86934a0f
--- /dev/null
+++ b/libc/src/sys/random/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(
+ getrandom
+ ALIAS
+ DEPENDS
+ .${LIBC_TARGET_OS}.getrandom
+)
diff --git a/libc/src/sys/random/getrandom.h b/libc/src/sys/random/getrandom.h
new file mode 100644
index 0000000000000..dab508d363ffd
--- /dev/null
+++ b/libc/src/sys/random/getrandom.h
@@ -0,0 +1,20 @@
+//===-- Implementation header for getrandom ----------------------*- 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_RANDOM_GETRANDOM_H
+#define LLVM_LIBC_SRC_SYS_RANDOM_GETRANDOM_H
+
+#include <sys/types.h>
+
+namespace __llvm_libc {
+
+ssize_t getrandom(void *buf, size_t buflen, unsigned int flags);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_SYS_RANDOM_GETRANDOM_H
diff --git a/libc/src/sys/random/linux/CMakeLists.txt b/libc/src/sys/random/linux/CMakeLists.txt
new file mode 100644
index 0000000000000..474e275ee597a
--- /dev/null
+++ b/libc/src/sys/random/linux/CMakeLists.txt
@@ -0,0 +1,12 @@
+add_entrypoint_object(
+ getrandom
+ SRCS
+ getrandom.cpp
+ HDRS
+ ../getrandom.h
+ DEPENDS
+ libc.include.sys_random
+ libc.include.sys_syscall
+ libc.src.__support.OSUtil.osutil
+ libc.src.errno.errno
+)
diff --git a/libc/src/sys/random/linux/getrandom.cpp b/libc/src/sys/random/linux/getrandom.cpp
new file mode 100644
index 0000000000000..e9c33da3d2940
--- /dev/null
+++ b/libc/src/sys/random/linux/getrandom.cpp
@@ -0,0 +1,29 @@
+//===-- Linux implementation of getrandom ---------------------------------===//
+//
+// 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/random/getrandom.h"
+
+#include "src/__support/OSUtil/syscall.h" // For internal syscall function.
+#include "src/__support/common.h"
+
+#include <errno.h>
+#include <sys/syscall.h> // For syscall numbers.
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(ssize_t, getrandom,
+ (void *buf, size_t buflen, unsigned int flags)) {
+ long ret = __llvm_libc::syscall_impl(SYS_getrandom, buf, buflen, flags);
+ if (ret < 0) {
+ errno = -ret;
+ return -1;
+ }
+ return 0;
+}
+
+} // namespace __llvm_libc
diff --git a/libc/test/src/sys/CMakeLists.txt b/libc/test/src/sys/CMakeLists.txt
index f8e25cc8d4e54..bf6283df87acb 100644
--- a/libc/test/src/sys/CMakeLists.txt
+++ b/libc/test/src/sys/CMakeLists.txt
@@ -1,4 +1,5 @@
add_subdirectory(mman)
+add_subdirectory(random)
add_subdirectory(resource)
add_subdirectory(sendfile)
add_subdirectory(stat)
diff --git a/libc/test/src/sys/random/CMakeLists.txt b/libc/test/src/sys/random/CMakeLists.txt
new file mode 100644
index 0000000000000..b4bbe81c92ff2
--- /dev/null
+++ b/libc/test/src/sys/random/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/random/linux/CMakeLists.txt b/libc/test/src/sys/random/linux/CMakeLists.txt
new file mode 100644
index 0000000000000..3dcfd8626c055
--- /dev/null
+++ b/libc/test/src/sys/random/linux/CMakeLists.txt
@@ -0,0 +1,17 @@
+add_libc_testsuite(libc_sys_random_unittests)
+
+add_libc_unittest(
+ getrandom_test
+ SUITE
+ libc_sys_random_unittests
+ SRCS
+ getrandom_test.cpp
+ DEPENDS
+ libc.include.errno
+ libc.include.math
+ libc.include.sys_random
+ libc.src.errno.errno
+ libc.src.math.fabs
+ libc.src.sys.random.getrandom
+ libc.test.errno_setter_matcher
+)
diff --git a/libc/test/src/sys/random/linux/getrandom_test.cpp b/libc/test/src/sys/random/linux/getrandom_test.cpp
new file mode 100644
index 0000000000000..669f197f30284
--- /dev/null
+++ b/libc/test/src/sys/random/linux/getrandom_test.cpp
@@ -0,0 +1,47 @@
+#include "src/math/fabs.h"
+#include "src/sys/random/getrandom.h"
+#include "test/ErrnoSetterMatcher.h"
+#include "utils/UnitTest/Test.h"
+
+TEST(LlvmLibcGetRandomTest, InvalidFlag) {
+ using __llvm_libc::testing::ErrnoSetterMatcher::Fails;
+ static constexpr size_t SIZE = 256;
+ char data[SIZE];
+ errno = 0;
+ ASSERT_THAT(__llvm_libc::getrandom(data, SIZE, -1), Fails(EINVAL));
+ errno = 0;
+}
+
+TEST(LlvmLibcGetRandomTest, InvalidBuffer) {
+ using __llvm_libc::testing::ErrnoSetterMatcher::Fails;
+
+ errno = 0;
+ ASSERT_THAT(__llvm_libc::getrandom(nullptr, 65536, 0), Fails(EFAULT));
+ errno = 0;
+}
+
+TEST(LlvmLibcGetRandomTest, PiEstimation) {
+ static constexpr size_t LIMIT = 10000000;
+ static constexpr double PI = 3.14159265358979;
+
+ auto generator = []() {
+ uint16_t data;
+ __llvm_libc::getrandom(&data, sizeof(data), 0);
+ return data;
+ };
+
+ auto sample = [&]() {
+ auto x = static_cast<double>(generator()) / 65536.0;
+ auto y = static_cast<double>(generator()) / 65536.0;
+ return x * x + y * y < 1.0;
+ };
+
+ double counter = 0;
+ for (size_t i = 0; i < LIMIT; ++i) {
+ if (sample()) {
+ counter += 1.0;
+ }
+ }
+ counter = counter / LIMIT * 4.0;
+ ASSERT_TRUE(__llvm_libc::fabs(counter - PI) < 0.1);
+}
More information about the libc-commits
mailing list