diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index 5e3ddd34fb4dc..b6ead64e208c7 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -730,6 +730,7 @@ if(LLVM_LIBC_FULL_BUILD) libc.src.stdlib.abort libc.src.stdlib.atexit libc.src.stdlib.exit + libc.src.stdlib.quick_exit libc.src.stdlib.getenv # signal.h entrypoints diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td index eb67c9b0b009b..9ec9ee7521c7e 100644 --- a/libc/spec/stdc.td +++ b/libc/spec/stdc.td @@ -1071,6 +1071,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 66% rename from libc/src/__support/OSUtil/baremetal/quick_exit.cpp rename to libc/src/__support/OSUtil/baremetal/exit.cpp index 5b6fcf42341eb..c9a166fedf3c1 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,16 @@ // //===----------------------------------------------------------------------===// -#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); namespace LIBC_NAMESPACE { +namespace internal { -[[noreturn]] void quick_exit(int status) { __llvm_libc_quick_exit(status); } +[[noreturn]] void exit(int status) { __llvm_libc_quick_exit(status); } + +} // namespace internal } // namespace LIBC_NAMESPACE diff --git a/libc/src/__support/OSUtil/quick_exit.h b/libc/src/__support/OSUtil/exit.h similarity index 71% rename from libc/src/__support/OSUtil/quick_exit.h rename to libc/src/__support/OSUtil/exit.h index e445917059c3e..694d3c92ca258 100644 --- a/libc/src/__support/OSUtil/quick_exit.h +++ b/libc/src/__support/OSUtil/exit.h @@ -6,13 +6,16 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_QUICK_EXIT_H -#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_QUICK_EXIT_H +#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_EXIT_H +#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_EXIT_H namespace LIBC_NAMESPACE { +namespace internal { -[[noreturn]] void quick_exit(int status); +[[noreturn]] void exit(int status); } +} // namespace LIBC_NAMESPACE + #endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_QUICK_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 87% rename from libc/src/__support/OSUtil/gpu/quick_exit.cpp rename to libc/src/__support/OSUtil/gpu/exit.cpp index af4795905e786..c99bb77c16e85 100644 --- a/libc/src/__support/OSUtil/gpu/quick_exit.cpp +++ b/libc/src/__support/OSUtil/gpu/exit.cpp @@ -6,14 +6,15 @@ // //===----------------------------------------------------------------------===// -#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 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 +26,5 @@ namespace LIBC_NAMESPACE { gpu::end_program(); } +} // namespace internal } // namespace LIBC_NAMESPACE 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 84% rename from libc/src/__support/OSUtil/linux/quick_exit.cpp rename to libc/src/__support/OSUtil/linux/exit.cpp index 51b3231d389f2..48c385129b1ae 100644 --- a/libc/src/__support/OSUtil/linux/quick_exit.cpp +++ b/libc/src/__support/OSUtil/linux/exit.cpp @@ -10,19 +10,17 @@ #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. #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..438ee3b3e00e0 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 @@ -56,6 +56,7 @@ LIBC_INLINE void report_assertion_failure(const char *assertion, // __builtin_trap as it could potentially be implemented using illegal // instructions which can be very misleading when debugging. #ifdef NDEBUG + #define LIBC_ASSERT(COND) \ do { \ } while (false) @@ -76,7 +77,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..59eeb71bfbfb9 100644 --- a/libc/src/stdlib/CMakeLists.txt +++ b/libc/src/stdlib/CMakeLists.txt @@ -432,6 +432,17 @@ add_entrypoint_object( ._Exit .atexit libc.src.__support.OSUtil.osutil + +) + +add_entrypoint_object( + quick_exit + SRCS + quick_exit.cpp + HDRS + quick_exit.h + DEPENDS + libc.src.__support.OSUtil.osutil ) add_entrypoint_object( 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..bee58163ed7b3 --- /dev/null +++ b/libc/src/stdlib/quick_exit.cpp @@ -0,0 +1,21 @@ +//===-- 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/stdlib/quick_exit.h b/libc/src/stdlib/quick_exit.h new file mode 100644 index 0000000000000..a2fdeedc853ca --- /dev/null +++ b/libc/src/stdlib/quick_exit.h @@ -0,0 +1,17 @@ +//===-- 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. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#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_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..3eedd6d678c0b 100644 --- a/libc/test/src/stdlib/CMakeLists.txt +++ b/libc/test/src/stdlib/CMakeLists.txt @@ -324,6 +324,19 @@ add_libc_test( libc.src.stdlib.srand ) +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 + ) + if(LLVM_LIBC_FULL_BUILD) 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..901b49efbc6b4 --- /dev/null +++ b/libc/test/src/stdlib/quick_exit_test.cpp @@ -0,0 +1,15 @@ +//===-- 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/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 446499cf15d7b..6b312fb848a47 100644 --- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel @@ -630,7 +630,7 @@ libc_support_library( ":__support_integer_to_string", ":__support_macros_attributes", ":__support_osutil_io", - ":__support_osutil_quick_exit", + ":__support_osutil_exit", ], ) @@ -1062,9 +1062,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"],