diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index 699bb9dcdf3c9..367db7d384d23 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -173,6 +173,7 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.stdlib.atoll libc.src.stdlib.bsearch libc.src.stdlib.div + libc.src.stdlib.quick_exit libc.src.stdlib.labs libc.src.stdlib.ldiv libc.src.stdlib.llabs diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td index ff700255144e6..109721b8b12a0 100644 --- a/libc/spec/stdc.td +++ b/libc/spec/stdc.td @@ -1072,6 +1072,7 @@ def StdC : StandardSpec<"stdc"> { FunctionSpec<"_Exit", RetValSpec, [ArgSpec]>, FunctionSpec<"exit", RetValSpec, [ArgSpec]>, FunctionSpec<"atexit", RetValSpec, [ArgSpec]>, + FunctionSpec<"quick_exit", RetValSpec, [ArgSpec]>, ] >; diff --git a/libc/src/__support/OSUtil/baremetal/CMakeLists.txt b/libc/src/__support/OSUtil/baremetal/CMakeLists.txt index e78301d104c1f..8f9200ad0bd96 100644 --- a/libc/src/__support/OSUtil/baremetal/CMakeLists.txt +++ b/libc/src/__support/OSUtil/baremetal/CMakeLists.txt @@ -2,7 +2,7 @@ add_object_library( baremetal_util SRCS io.cpp - quick_exit.cpp + exit.cpp HDRS io.h DEPENDS diff --git a/libc/src/__support/OSUtil/baremetal/quick_exit.cpp b/libc/src/__support/OSUtil/baremetal/exit.cpp similarity index 54% rename from libc/src/__support/OSUtil/baremetal/quick_exit.cpp rename to libc/src/__support/OSUtil/baremetal/exit.cpp index 5b6fcf42341eb..08473f7f3b00b 100644 --- a/libc/src/__support/OSUtil/baremetal/quick_exit.cpp +++ b/libc/src/__support/OSUtil/baremetal/exit.cpp @@ -1,4 +1,4 @@ -//===----- Baremetal implementation of a quick exit function ----*- C++ -*-===// +//===-------- Baremetal implementation of an 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. @@ -6,13 +6,13 @@ // //===----------------------------------------------------------------------===// -#include "src/__support/OSUtil/quick_exit.h" +#include "src/__support/OSUtil/exit.h" // This is intended to be provided by the vendor. -extern "C" [[noreturn]] void __llvm_libc_quick_exit(int status); +extern "C" [[noreturn]] void __llvm_libc_exit(int status); -namespace LIBC_NAMESPACE { +namespace LIBC_NAMESPACE::internal { -[[noreturn]] void quick_exit(int status) { __llvm_libc_quick_exit(status); } +[[noreturn]] void exit(int status) { __llvm_libc_exit(status); } -} // namespace LIBC_NAMESPACE +} // namespace LIBC_NAMESPACE::internal diff --git a/libc/src/__support/OSUtil/exit.h b/libc/src/__support/OSUtil/exit.h new file mode 100644 index 0000000000000..f01e4c70502f6 --- /dev/null +++ b/libc/src/__support/OSUtil/exit.h @@ -0,0 +1,18 @@ +//===------------ Implementation of an 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_EXIT_H +#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_EXIT_H + +namespace LIBC_NAMESPACE::internal { + +[[noreturn]] void exit(int status); + +} + +#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_EXIT_H diff --git a/libc/src/__support/OSUtil/gpu/CMakeLists.txt b/libc/src/__support/OSUtil/gpu/CMakeLists.txt index 0c89f9223678b..6cb3aa30f249e 100644 --- a/libc/src/__support/OSUtil/gpu/CMakeLists.txt +++ b/libc/src/__support/OSUtil/gpu/CMakeLists.txt @@ -1,7 +1,7 @@ add_object_library( gpu_util SRCS - quick_exit.cpp + exit.cpp io.cpp HDRS io.h diff --git a/libc/src/__support/OSUtil/gpu/quick_exit.cpp b/libc/src/__support/OSUtil/gpu/exit.cpp similarity index 77% rename from libc/src/__support/OSUtil/gpu/quick_exit.cpp rename to libc/src/__support/OSUtil/gpu/exit.cpp index af4795905e786..96acb549bb7ab 100644 --- a/libc/src/__support/OSUtil/gpu/quick_exit.cpp +++ b/libc/src/__support/OSUtil/gpu/exit.cpp @@ -1,4 +1,4 @@ -//===---------- GPU implementation of a quick exit function -----*- C++ -*-===// +//===------------- GPU implementation of an 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. @@ -6,14 +6,14 @@ // //===----------------------------------------------------------------------===// -#include "src/__support/OSUtil/quick_exit.h" +#include "src/__support/OSUtil/exit.h" #include "src/__support/RPC/rpc_client.h" #include "src/__support/macros/properties/architectures.h" -namespace LIBC_NAMESPACE { +namespace LIBC_NAMESPACE::internal { -[[noreturn]] void quick_exit(int status) { +[[noreturn]] void exit(int status) { // We want to first make sure the server is listening before we exit. rpc::Client::Port port = rpc::client.open(); port.send_and_recv([](rpc::Buffer *) {}, [](rpc::Buffer *) {}); @@ -25,4 +25,4 @@ namespace LIBC_NAMESPACE { gpu::end_program(); } -} // namespace LIBC_NAMESPACE +} // namespace LIBC_NAMESPACE::internal diff --git a/libc/src/__support/OSUtil/linux/CMakeLists.txt b/libc/src/__support/OSUtil/linux/CMakeLists.txt index 239d115704927..9a55232d532fe 100644 --- a/libc/src/__support/OSUtil/linux/CMakeLists.txt +++ b/libc/src/__support/OSUtil/linux/CMakeLists.txt @@ -7,7 +7,7 @@ add_subdirectory(${LIBC_TARGET_ARCHITECTURE}) add_object_library( linux_util SRCS - quick_exit.cpp + exit.cpp HDRS io.h syscall.h diff --git a/libc/src/__support/OSUtil/linux/quick_exit.cpp b/libc/src/__support/OSUtil/linux/exit.cpp similarity index 71% rename from libc/src/__support/OSUtil/linux/quick_exit.cpp rename to libc/src/__support/OSUtil/linux/exit.cpp index 51b3231d389f2..ee904155c537d 100644 --- a/libc/src/__support/OSUtil/linux/quick_exit.cpp +++ b/libc/src/__support/OSUtil/linux/exit.cpp @@ -1,4 +1,4 @@ -//===---------- Linux implementation of a quick exit function ---*- C++ -*-===// +//===------------ Linux implementation of an 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. @@ -10,19 +10,19 @@ #include "syscall.h" // For internal syscall function. #include // For syscall numbers. -namespace LIBC_NAMESPACE { +namespace LIBC_NAMESPACE::internal { // mark as no_stack_protector for x86 since TLS can be torn down before calling -// quick_exit so that the stack protector canary cannot be loaded. +// exit so that the stack protector canary cannot be loaded. #ifdef LIBC_TARGET_ARCH_IS_X86 -__attribute__((no_stack_protector)) +[[clang::no_stack_protector]] #endif -__attribute__((noreturn)) void -quick_exit(int status) { +[[noreturn]] void +exit(int status) { for (;;) { LIBC_NAMESPACE::syscall_impl(SYS_exit_group, status); LIBC_NAMESPACE::syscall_impl(SYS_exit, status); } } -} // namespace LIBC_NAMESPACE +} // namespace LIBC_NAMESPACE::internal diff --git a/libc/src/__support/libc_assert.h b/libc/src/__support/libc_assert.h index 61f075435b552..ed06cc329809f 100644 --- a/libc/src/__support/libc_assert.h +++ b/libc/src/__support/libc_assert.h @@ -20,8 +20,8 @@ #else // Not LIBC_COPT_USE_C_ASSERT +#include "src/__support/OSUtil/exit.h" #include "src/__support/OSUtil/io.h" -#include "src/__support/OSUtil/quick_exit.h" #include "src/__support/integer_to_string.h" #include "src/__support/macros/attributes.h" // For LIBC_INLINE @@ -51,7 +51,7 @@ LIBC_INLINE void report_assertion_failure(const char *assertion, // The public "assert" macro calls abort on failure. Should it be same here? // The libc internal assert can fire from anywhere inside the libc. So, to -// avoid potential chicken-and-egg problems, it is simple to do a quick_exit +// avoid potential chicken-and-egg problems, it is simple to do an exit // on assertion failure instead of calling abort. We also don't want to use // __builtin_trap as it could potentially be implemented using illegal // instructions which can be very misleading when debugging. @@ -76,7 +76,7 @@ LIBC_INLINE void report_assertion_failure(const char *assertion, "' in function: '"); \ LIBC_NAMESPACE::write_to_stderr(__PRETTY_FUNCTION__); \ LIBC_NAMESPACE::write_to_stderr("'\n"); \ - LIBC_NAMESPACE::quick_exit(0xFF); \ + LIBC_NAMESPACE::internal::exit(0xFF); \ } \ } while (false) #endif // NDEBUG diff --git a/libc/src/stdlib/CMakeLists.txt b/libc/src/stdlib/CMakeLists.txt index 9b76a6a0f8575..e0bff5198b590 100644 --- a/libc/src/stdlib/CMakeLists.txt +++ b/libc/src/stdlib/CMakeLists.txt @@ -42,6 +42,16 @@ add_entrypoint_object( libc.src.__support.str_to_integer ) +add_entrypoint_object( + quick_exit + SRCS + quick_exit.cpp + HDRS + quick_exit.h + DEPENDS + libc.src.__support.OSUtil.osutil +) + add_entrypoint_object( getenv SRCS diff --git a/libc/src/stdlib/_Exit.cpp b/libc/src/stdlib/_Exit.cpp index 233af20973924..03a766261014e 100644 --- a/libc/src/stdlib/_Exit.cpp +++ b/libc/src/stdlib/_Exit.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "src/__support/OSUtil/quick_exit.h" +#include "src/__support/OSUtil/exit.h" #include "src/__support/common.h" #include "src/stdlib/_Exit.h" @@ -14,7 +14,7 @@ namespace LIBC_NAMESPACE { [[noreturn]] LLVM_LIBC_FUNCTION(void, _Exit, (int status)) { - quick_exit(status); + internal::exit(status); } } // namespace LIBC_NAMESPACE diff --git a/libc/src/stdlib/exit.cpp b/libc/src/stdlib/exit.cpp index ba87bffaeb541..1f7ccbb556607 100644 --- a/libc/src/stdlib/exit.cpp +++ b/libc/src/stdlib/exit.cpp @@ -7,7 +7,7 @@ //===----------------------------------------------------------------------===// #include "src/stdlib/exit.h" -#include "src/__support/OSUtil/quick_exit.h" +#include "src/__support/OSUtil/exit.h" #include "src/__support/common.h" extern "C" void __cxa_finalize(void *); @@ -16,7 +16,7 @@ namespace LIBC_NAMESPACE { [[noreturn]] LLVM_LIBC_FUNCTION(void, exit, (int status)) { __cxa_finalize(nullptr); - quick_exit(status); + internal::exit(status); } } // namespace LIBC_NAMESPACE diff --git a/libc/src/stdlib/quick_exit.cpp b/libc/src/stdlib/quick_exit.cpp new file mode 100644 index 0000000000000..cf7f07bf2439a --- /dev/null +++ b/libc/src/stdlib/quick_exit.cpp @@ -0,0 +1,22 @@ +//===-- Implementation of quick_exit --------------------------------------===// +// +// 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/stdlib/quick_exit.h" +#include "src/__support/OSUtil/exit.h" +#include "src/__support/common.h" + +// extern "C" void __cxa_finalize(void *); + +namespace LIBC_NAMESPACE { + +[[noreturn]] LLVM_LIBC_FUNCTION(void, quick_exit, (int status)) { + // __cxa_finalize(nullptr); + internal::exit(status); +} + +} // namespace LIBC_NAMESPACE diff --git a/libc/src/__support/OSUtil/quick_exit.h b/libc/src/stdlib/quick_exit.h similarity index 62% rename from libc/src/__support/OSUtil/quick_exit.h rename to libc/src/stdlib/quick_exit.h index e445917059c3e..9a3c20ccd9b17 100644 --- a/libc/src/__support/OSUtil/quick_exit.h +++ b/libc/src/stdlib/quick_exit.h @@ -1,4 +1,4 @@ -//===---------- Implementation of a quick exit function ---------*- C++ -*-===// +//===-- Implementation header for quick_exit --------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,13 +6,13 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_QUICK_EXIT_H -#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_QUICK_EXIT_H +#ifndef LLVM_LIBC_SRC_STDLIB_QUICK_EXIT_H +#define LLVM_LIBC_SRC_STDLIB_QUICK_EXIT_H namespace LIBC_NAMESPACE { [[noreturn]] void quick_exit(int status); -} +} // namespace LIBC_NAMESPACE -#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_QUICK_EXIT_H +#endif // LLVM_LIBC_SRC_STDLIB_QUICK_EXIT_H diff --git a/libc/src/unistd/_exit.cpp b/libc/src/unistd/_exit.cpp index 6fbf3a51d42f4..4b652a2c13fd1 100644 --- a/libc/src/unistd/_exit.cpp +++ b/libc/src/unistd/_exit.cpp @@ -7,13 +7,13 @@ //===----------------------------------------------------------------------===// #include "src/unistd/_exit.h" -#include "src/__support/OSUtil/quick_exit.h" +#include "src/__support/OSUtil/exit.h" #include "src/__support/common.h" namespace LIBC_NAMESPACE { [[noreturn]] LLVM_LIBC_FUNCTION(void, _exit, (int status)) { - quick_exit(status); + internal::exit(status); } } // namespace LIBC_NAMESPACE diff --git a/libc/test/IntegrationTest/test.h b/libc/test/IntegrationTest/test.h index 64906ef179391..5be66d9edff02 100644 --- a/libc/test/IntegrationTest/test.h +++ b/libc/test/IntegrationTest/test.h @@ -9,8 +9,8 @@ #ifndef LLVM_LIBC_UTILS_INTEGRATION_TEST_TEST_H #define LLVM_LIBC_UTILS_INTEGRATION_TEST_TEST_H +#include "src/__support/OSUtil/exit.h" #include "src/__support/OSUtil/io.h" -#include "src/__support/OSUtil/quick_exit.h" #define __AS_STRING(val) #val #define __CHECK_TRUE(file, line, val, should_exit) \ @@ -18,7 +18,7 @@ LIBC_NAMESPACE::write_to_stderr(file ":" __AS_STRING( \ line) ": Expected '" #val "' to be true, but is false\n"); \ if (should_exit) \ - LIBC_NAMESPACE::quick_exit(127); \ + LIBC_NAMESPACE::internal::exit(127); \ } #define __CHECK_FALSE(file, line, val, should_exit) \ @@ -26,7 +26,7 @@ LIBC_NAMESPACE::write_to_stderr(file ":" __AS_STRING( \ line) ": Expected '" #val "' to be false, but is true\n"); \ if (should_exit) \ - LIBC_NAMESPACE::quick_exit(127); \ + LIBC_NAMESPACE::internal::exit(127); \ } #define __CHECK_EQ(file, line, val1, val2, should_exit) \ @@ -34,7 +34,7 @@ LIBC_NAMESPACE::write_to_stderr(file ":" __AS_STRING( \ line) ": Expected '" #val1 "' to be equal to '" #val2 "'\n"); \ if (should_exit) \ - LIBC_NAMESPACE::quick_exit(127); \ + LIBC_NAMESPACE::internal::exit(127); \ } #define __CHECK_NE(file, line, val1, val2, should_exit) \ @@ -42,7 +42,7 @@ LIBC_NAMESPACE::write_to_stderr(file ":" __AS_STRING( \ line) ": Expected '" #val1 "' to not be equal to '" #val2 "'\n"); \ if (should_exit) \ - LIBC_NAMESPACE::quick_exit(127); \ + LIBC_NAMESPACE::internal::exit(127); \ } //////////////////////////////////////////////////////////////////////////////// diff --git a/libc/test/src/stdlib/CMakeLists.txt b/libc/test/src/stdlib/CMakeLists.txt index 28c5b566cc477..6a7faedece380 100644 --- a/libc/test/src/stdlib/CMakeLists.txt +++ b/libc/test/src/stdlib/CMakeLists.txt @@ -373,6 +373,19 @@ if(LLVM_LIBC_FULL_BUILD) libc.src.signal.raise ) + add_libc_test( + quick_exit_test + # The EXPECT_EXITS test is only availible for unit tests. + UNIT_TEST_ONLY + SUITE + libc-stdlib-tests + SRCS + quick_exit_test.cpp + DEPENDS + libc.include.stdlib + libc.src.stdlib.quick_exit + ) + # Only the GPU has an in-tree 'malloc' implementation. if(LIBC_TARGET_OS_IS_GPU) add_libc_test( diff --git a/libc/test/src/stdlib/quick_exit_test.cpp b/libc/test/src/stdlib/quick_exit_test.cpp new file mode 100644 index 0000000000000..3af7c74a128c5 --- /dev/null +++ b/libc/test/src/stdlib/quick_exit_test.cpp @@ -0,0 +1,16 @@ +//===-- Unittests for quick_exit ------------------------------------------===// +// +// 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/stdlib/exit.h" +#include "src/stdlib/quick_exit.h" +#include "test/UnitTest/Test.h" + +TEST(LlvmLibcStdlib, quick_exit) { + EXPECT_EXITS([] { LIBC_NAMESPACE::quick_exit(1); }, 1); + EXPECT_EXITS([] { LIBC_NAMESPACE::quick_exit(65); }, 65); +} diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel index 09a7395eab3f6..1f7a2f8a9f9fd 100644 --- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel @@ -641,7 +641,7 @@ libc_support_library( ":__support_integer_to_string", ":__support_macros_attributes", ":__support_osutil_io", - ":__support_osutil_quick_exit", + ":__support_osutil_exit", ], ) @@ -1073,9 +1073,9 @@ libc_support_library( ) libc_support_library( - name = "__support_osutil_quick_exit", - srcs = ["src/__support/OSUtil/linux/quick_exit.cpp"], - hdrs = ["src/__support/OSUtil/quick_exit.h"], + name = "__support_osutil_exit", + srcs = ["src/__support/OSUtil/linux/exit.cpp"], + hdrs = ["src/__support/OSUtil/exit.h"], target_compatible_with = select({ "@platforms//os:linux": [], "//conditions:default": ["@platforms//:incompatible"],