diff --git a/libc/src/__support/CMakeLists.txt b/libc/src/__support/CMakeLists.txt --- a/libc/src/__support/CMakeLists.txt +++ b/libc/src/__support/CMakeLists.txt @@ -54,3 +54,4 @@ ) add_subdirectory(FPUtil) +add_subdirectory(OSUtil) diff --git a/libc/src/__support/OSUtil/CMakeLists.txt b/libc/src/__support/OSUtil/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/libc/src/__support/OSUtil/CMakeLists.txt @@ -0,0 +1,10 @@ +add_subdirectory(linux) + +add_header_library( + osutil + HDRS + io.h + quick_exit.h + DEPENDS + libc.src.__support.OSUtil.linux.linux_util +) diff --git a/libc/src/__support/OSUtil/io.h b/libc/src/__support/OSUtil/io.h new file mode 100644 --- /dev/null +++ b/libc/src/__support/OSUtil/io.h @@ -0,0 +1,16 @@ +//===---------------- Implementation of IO utils ----------------*- 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_IO_H +#define LLVM_LIBC_SRC_SUPPORT_OSUTIL_IO_H + +#ifdef __unix__ +#include "linux/io.h" +#endif + +#endif // LLVM_LIBC_SRC_SUPPORT_OSUTIL_IO_H diff --git a/libc/src/__support/OSUtil/linux/CMakeLists.txt b/libc/src/__support/OSUtil/linux/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/libc/src/__support/OSUtil/linux/CMakeLists.txt @@ -0,0 +1,10 @@ +add_header_library( + linux_util + HDRS + io.h + quick_exit.h + DEPENDS + libc.config.linux.linux_syscall_h + libc.include.sys_syscall + libc.src.string.string_utils +) diff --git a/libc/src/__support/OSUtil/linux/io.h b/libc/src/__support/OSUtil/linux/io.h new file mode 100644 --- /dev/null +++ b/libc/src/__support/OSUtil/linux/io.h @@ -0,0 +1,25 @@ +//===-------------- Linux implementation of IO utils ------------*- 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_LINUX_IO_H +#define LLVM_LIBC_SRC_SUPPORT_OSUTIL_LINUX_IO_H + +#include "config/linux/syscall.h" // For internal syscall function. +#include "include/sys/syscall.h" // For syscall numbers. +#include "src/string/string_utils.h" + +namespace __llvm_libc { + +static inline void write_to_stderr(const char *msg) { + __llvm_libc::syscall(SYS_write, 2 /* stderr */, msg, + internal::string_length(msg)); +} + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_SUPPORT_OSUTIL_LINUX_IO_H diff --git a/libc/src/__support/OSUtil/linux/quick_exit.h b/libc/src/__support/OSUtil/linux/quick_exit.h new file mode 100644 --- /dev/null +++ b/libc/src/__support/OSUtil/linux/quick_exit.h @@ -0,0 +1,26 @@ +//===---------- Linux implementation of a quick exit 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_LINUX_QUICK_EXIT_H +#define LLVM_LIBC_SRC_SUPPORT_OSUTIL_LINUX_QUICK_EXIT_H + +#include "config/linux/syscall.h" // For internal syscall function. +#include "include/sys/syscall.h" // For syscall numbers. + +namespace __llvm_libc { + +static inline void quick_exit(int status) { + for (;;) { + __llvm_libc::syscall(SYS_exit_group, status); + __llvm_libc::syscall(SYS_exit, status); + } +} + +} // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_SUPPORT_OSUTIL_LINUX_QUICK_EXIT_H diff --git a/libc/src/__support/OSUtil/quick_exit.h b/libc/src/__support/OSUtil/quick_exit.h new file mode 100644 --- /dev/null +++ b/libc/src/__support/OSUtil/quick_exit.h @@ -0,0 +1,16 @@ +//===---------- Implementation of a quick exit 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_QUICK_EXIT_H +#define LLVM_LIBC_SRC_SUPPORT_OSUTIL_QUICK_EXIT_H + +#ifdef __unix__ +#include "linux/quick_exit.h" +#endif + +#endif // LLVM_LIBC_SRC_SUPPORT_OSUTIL_QUICK_EXIT_H diff --git a/libc/test/loader/linux/CMakeLists.txt b/libc/test/loader/linux/CMakeLists.txt --- a/libc/test/loader/linux/CMakeLists.txt +++ b/libc/test/loader/linux/CMakeLists.txt @@ -3,16 +3,21 @@ return() endif() +add_header_library( + loader_test + HDRS + loader_test.h + DEPENDS + libc.src.__support.OSUtil.osutil +) + add_loader_test( loader_args_test SRC args_test.cpp DEPENDS + .loader_test libc.loader.linux.crt1 - libc.src.assert.__assert_fail - libc.src.signal.raise - libc.src.stdlib._Exit - libc.src.stdlib.abort ARGS 1 2 3 ENV @@ -25,6 +30,7 @@ SRC main_without_envp.cpp DEPENDS + .loader_test libc.loader.linux.crt1 ) @@ -33,6 +39,7 @@ SRC main_without_args.cpp DEPENDS + .loader_test libc.loader.linux.crt1 ) diff --git a/libc/test/loader/linux/args_test.cpp b/libc/test/loader/linux/args_test.cpp --- a/libc/test/loader/linux/args_test.cpp +++ b/libc/test/loader/linux/args_test.cpp @@ -6,8 +6,7 @@ // //===----------------------------------------------------------------------===// -#undef NDEBUG -#include "src/assert/assert.h" +#include "loader_test.h" static bool my_streq(const char *lhs, const char *rhs) { const char *l, *r; @@ -19,10 +18,10 @@ } int main(int argc, char **argv, char **envp) { - assert(argc == 4 && "Unexpected argc."); - assert(my_streq(argv[1], "1") && "Unexpected argv[1]."); - assert(my_streq(argv[2], "2") && "Unexpected argv[2]."); - assert(my_streq(argv[3], "3") && "Unexpected argv[3]."); + ASSERT_TRUE(argc == 4); + ASSERT_TRUE(my_streq(argv[1], "1")); + ASSERT_TRUE(my_streq(argv[2], "2")); + ASSERT_TRUE(my_streq(argv[3], "3")); bool found_france = false; bool found_germany = false; @@ -33,8 +32,7 @@ found_germany = true; } - assert(found_france && found_germany && - "Did not find whats expected in envp."); + ASSERT_TRUE(found_france && found_germany); return 0; } diff --git a/libc/test/loader/linux/loader_test.h b/libc/test/loader/linux/loader_test.h new file mode 100644 --- /dev/null +++ b/libc/test/loader/linux/loader_test.h @@ -0,0 +1,27 @@ +//===-- Simple checkers for loader tests ------------------------*- 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_TEST_LOADER_LINUX_LOADER_TEST_H +#define LLVM_LIBC_TEST_LOADER_LINUX_LOADER_TEST_H + +#include "src/__support/OSUtil/io.h" +#include "src/__support/OSUtil/quick_exit.h" + +#define __AS_STRING(val) #val +#define __CHECK(file, line, val, should_exit) \ + if (!(val)) { \ + __llvm_libc::write_to_stderr(file ":" __AS_STRING( \ + line) ": Expected '" #val "' to be true, but is false\n"); \ + if (should_exit) \ + __llvm_libc::quick_exit(127); \ + } + +#define EXPECT_TRUE(val) __CHECK(__FILE__, __LINE__, val, false) +#define ASSERT_TRUE(val) __CHECK(__FILE__, __LINE__, val, true) + +#endif // LLVM_LIBC_TEST_LOADER_LINUX_LOADER_TEST_H