];
}
+def StdlibAPI : PublicAPI<"stdlib.h"> {
+ let Functions = [
+ "_Exit",
+ "abort",
+ ];
+}
+
def ErrnoAPI : PublicAPI<"errno.h"> {
let Macros = [
ErrnoMacro,
../config/${LIBC_TARGET_OS}/signal.h.in
)
+add_gen_header(
+ stdlib_h
+ DEF_FILE stdlib.h.def
+ GEN_HDR stdlib.h
+ DEPENDS
+ llvm_libc_common_h
+)
+
# TODO: Not all platforms will have a include/sys directory. Add the sys
# directory and the targets for sys/*.h files conditional to the OS requiring
# them.
#undef __END_C_DECLS
#define __END_C_DECLS }
+#undef _Noreturn
+#define _Noreturn [[noreturn]]
+
#else // not __cplusplus
#undef __BEGIN_C_DECLS
--- /dev/null
+//===---------------- C standard library header stdlib.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_STDLIB_H
+#define LLVM_LIBC_STDLIB_H
+
+#include <__llvm-libc-common.h>
+
+%%public_api()
+
+#endif // LLVM_LIBC_STDLIB_H
sigaddset
sigemptyset
sigprocmask
+
+ # stdlib.h entrypoints
+ _Exit
+ abort
)
add_entrypoint_library(
def VoidPtr : PtrType<VoidType>;
def SizeTType : NamedType<"size_t">;
+// _Noreturn is really not a type, but it is convenient to treat it as a type.
+def NoReturn : NamedType<"_Noreturn void">;
+
class Macro<string name> {
string Name = name;
}
]
>;
+ HeaderSpec StdLib = HeaderSpec<
+ "stdlib.h",
+ [], // Macros
+ [], // Types
+ [], // Enumerations
+ [
+ FunctionSpec<"abort", RetValSpec<NoReturn>, [ArgSpec<VoidType>]>,
+ FunctionSpec<"_Exit", RetValSpec<NoReturn>, [ArgSpec<IntType>]>,
+ ]
+ >;
+
HeaderSpec Errno = HeaderSpec<
"errno.h",
[
Math,
String,
StdIO,
+ StdLib,
Signal,
Threads,
];
add_subdirectory(errno)
add_subdirectory(math)
add_subdirectory(signal)
+add_subdirectory(stdlib)
add_subdirectory(string)
# TODO: Add this target conditional to the target OS.
add_subdirectory(sys)
--- /dev/null
+if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
+ add_subdirectory(${LIBC_TARGET_OS})
+endif()
+
+add_entrypoint_object(
+ abort
+ SRCS
+ abort.cpp
+ HDRS
+ abort.h
+ DEPENDS
+ raise
+ _Exit
+ stdlib_h
+)
--- /dev/null
+//===----------------- Implementation header for _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__EXIT_H
+#define LLVM_LIBC_SRC__EXIT_H
+
+namespace __llvm_libc {
+
+[[noreturn]] void _Exit(int status);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC__EXIT_H
--- /dev/null
+//===---------------------- Implementation of abort -----------------------===//
+//
+// 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/__support/common.h"
+#include "src/signal/raise.h"
+#include "src/stdlib/_Exit.h"
+
+#include "src/stdlib/abort.h"
+
+namespace __llvm_libc {
+
+void LLVM_LIBC_ENTRYPOINT(abort)() {
+ // TODO: When sigprocmask and sigaction land:
+ // Unblock SIGABRT, raise it, if it was ignored or the handler returned,
+ // change its action to SIG_DFL, raise it again.
+ // TODO: When C11 mutexes land:
+ // Aquire recursive mutex (in case the current signal handler for SIGABRT
+ // itself calls abort we don't want to deadlock on the same thread trying
+ // to aquire it's own mutex.)
+ __llvm_libc::raise(SIGABRT);
+ __llvm_libc::raise(SIGKILL);
+ __llvm_libc::_Exit(127);
+}
+
+} // namespace __llvm_libc
--- /dev/null
+//===----------------- Implementation header for abort ---------*- 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_ABORT_H
+#define LLVM_LIBC_SRC_ABORT_H
+
+namespace __llvm_libc {
+
+[[noreturn]] void abort();
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_ABORT_H
--- /dev/null
+add_entrypoint_object(
+ _Exit
+ SRCS
+ _Exit.cpp
+ HDRS
+ ../_Exit.h
+ DEPENDS
+ sys_syscall_h
+ linux_syscall_h
+ stdlib_h
+)
--- /dev/null
+//===------------------- Linux Implementation of _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 "config/linux/syscall.h" // For internal syscall function.
+#include "include/sys/syscall.h" // For syscall numbers.
+#include "src/__support/common.h"
+
+#include "src/stdlib/_Exit.h"
+
+namespace __llvm_libc {
+
+void LLVM_LIBC_ENTRYPOINT(_Exit)(int status) {
+ for (;;) {
+ __llvm_libc::syscall(SYS_exit_group, status);
+ __llvm_libc::syscall(SYS_exit, status);
+ }
+}
+
+} // namespace __llvm_libc
add_subdirectory(errno)
add_subdirectory(signal)
+add_subdirectory(stdlib)
add_subdirectory(string)
add_subdirectory(sys)
--- /dev/null
+add_libc_testsuite(libc_stdlib_unittests)
+
+add_libc_unittest(
+ _Exit_test
+ SUITE
+ libc_stdlib_unittests
+ SRCS
+ _Exit_test.cpp
+ DEPENDS
+ stdlib_h
+ _Exit
+)
+
+add_libc_unittest(
+ abort_test
+ SUITE
+ libc_stdlib_unittests
+ SRCS
+ abort_test.cpp
+ DEPENDS
+ stdlib_h
+ signal_h
+ abort
+ _Exit
+ raise
+)
--- /dev/null
+//===----------------------- Unittests for _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 "include/stdlib.h"
+#include "src/stdlib/_Exit.h"
+#include "utils/UnitTest/Test.h"
+
+TEST(Stdlib, _Exit) {
+ EXPECT_EXITS([] { __llvm_libc::_Exit(1); }, 1);
+ EXPECT_EXITS([] { __llvm_libc::_Exit(65); }, 65);
+}
--- /dev/null
+//===----------------------- Unittests for abort --------------------------===//
+//
+// 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 "include/signal.h"
+#include "include/stdlib.h"
+#include "src/stdlib/abort.h"
+#include "utils/UnitTest/Test.h"
+
+TEST(Stdlib, abort) {
+ // -1 matches against any signal, which is necessary for now until
+ // __llvm_libc::abort() unblocks SIGABRT.
+ EXPECT_DEATH([] { __llvm_libc::abort(); }, -1);
+}