[libc-commits] [libc] a499d68 - [libc] Create abort and _Exit
Alex Brachet via libc-commits
libc-commits at lists.llvm.org
Thu Mar 5 11:22:53 PST 2020
Author: Alex Brachet
Date: 2020-03-05T14:21:18-05:00
New Revision: a499d6805664350095658878e25f6ae20a106748
URL: https://github.com/llvm/llvm-project/commit/a499d6805664350095658878e25f6ae20a106748
DIFF: https://github.com/llvm/llvm-project/commit/a499d6805664350095658878e25f6ae20a106748.diff
LOG: [libc] Create abort and _Exit
This revision creates abort and _Exit implementations
Differential Revision: https://reviews.llvm.org/D74949
Added:
libc/include/stdlib.h.def
libc/src/stdlib/CMakeLists.txt
libc/src/stdlib/_Exit.h
libc/src/stdlib/abort.cpp
libc/src/stdlib/abort.h
libc/src/stdlib/linux/CMakeLists.txt
libc/src/stdlib/linux/_Exit.cpp
libc/test/src/stdlib/CMakeLists.txt
libc/test/src/stdlib/_Exit_test.cpp
libc/test/src/stdlib/abort_test.cpp
Modified:
libc/config/linux/api.td
libc/include/CMakeLists.txt
libc/include/__llvm-libc-common.h
libc/lib/CMakeLists.txt
libc/spec/spec.td
libc/spec/stdc.td
libc/src/CMakeLists.txt
libc/test/src/CMakeLists.txt
Removed:
################################################################################
diff --git a/libc/config/linux/api.td b/libc/config/linux/api.td
index 3ed556a93c03..1c9fa8a36c2e 100644
--- a/libc/config/linux/api.td
+++ b/libc/config/linux/api.td
@@ -84,6 +84,13 @@ def StdIOAPI : PublicAPI<"stdio.h"> {
];
}
+def StdlibAPI : PublicAPI<"stdlib.h"> {
+ let Functions = [
+ "_Exit",
+ "abort",
+ ];
+}
+
def ErrnoAPI : PublicAPI<"errno.h"> {
let Macros = [
ErrnoMacro,
diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index 612b53196270..db5f371f75f3 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -63,6 +63,14 @@ add_gen_header(
../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.
diff --git a/libc/include/__llvm-libc-common.h b/libc/include/__llvm-libc-common.h
index 7dc2f9e4e6d5..18b74e387800 100644
--- a/libc/include/__llvm-libc-common.h
+++ b/libc/include/__llvm-libc-common.h
@@ -17,6 +17,9 @@
#undef __END_C_DECLS
#define __END_C_DECLS }
+#undef _Noreturn
+#define _Noreturn [[noreturn]]
+
#else // not __cplusplus
#undef __BEGIN_C_DECLS
diff --git a/libc/include/stdlib.h.def b/libc/include/stdlib.h.def
new file mode 100644
index 000000000000..97e3846350c7
--- /dev/null
+++ b/libc/include/stdlib.h.def
@@ -0,0 +1,16 @@
+//===---------------- 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
diff --git a/libc/lib/CMakeLists.txt b/libc/lib/CMakeLists.txt
index b4ab4109d167..b67f8e4c686b 100644
--- a/libc/lib/CMakeLists.txt
+++ b/libc/lib/CMakeLists.txt
@@ -18,6 +18,10 @@ add_entrypoint_library(
sigaddset
sigemptyset
sigprocmask
+
+ # stdlib.h entrypoints
+ _Exit
+ abort
)
add_entrypoint_library(
diff --git a/libc/spec/spec.td b/libc/spec/spec.td
index 2272ef3da368..979efeaf066f 100644
--- a/libc/spec/spec.td
+++ b/libc/spec/spec.td
@@ -48,6 +48,9 @@ def CharType : NamedType<"char">;
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;
}
diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index 0eff0205d74a..babfce4b6ad2 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -178,6 +178,17 @@ def StdC : StandardSpec<"stdc"> {
]
>;
+ 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",
[
@@ -278,6 +289,7 @@ def StdC : StandardSpec<"stdc"> {
Math,
String,
StdIO,
+ StdLib,
Signal,
Threads,
];
diff --git a/libc/src/CMakeLists.txt b/libc/src/CMakeLists.txt
index 0ff0a6ae70cd..7f8ef92e6cc5 100644
--- a/libc/src/CMakeLists.txt
+++ b/libc/src/CMakeLists.txt
@@ -1,6 +1,7 @@
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)
diff --git a/libc/src/stdlib/CMakeLists.txt b/libc/src/stdlib/CMakeLists.txt
new file mode 100644
index 000000000000..52beeb1ab135
--- /dev/null
+++ b/libc/src/stdlib/CMakeLists.txt
@@ -0,0 +1,15 @@
+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
+)
diff --git a/libc/src/stdlib/_Exit.h b/libc/src/stdlib/_Exit.h
new file mode 100644
index 000000000000..4ac5dd850c07
--- /dev/null
+++ b/libc/src/stdlib/_Exit.h
@@ -0,0 +1,18 @@
+//===----------------- 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
diff --git a/libc/src/stdlib/abort.cpp b/libc/src/stdlib/abort.cpp
new file mode 100644
index 000000000000..777e3fd649ec
--- /dev/null
+++ b/libc/src/stdlib/abort.cpp
@@ -0,0 +1,30 @@
+//===---------------------- 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
diff --git a/libc/src/stdlib/abort.h b/libc/src/stdlib/abort.h
new file mode 100644
index 000000000000..4bf347bb805f
--- /dev/null
+++ b/libc/src/stdlib/abort.h
@@ -0,0 +1,18 @@
+//===----------------- 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
diff --git a/libc/src/stdlib/linux/CMakeLists.txt b/libc/src/stdlib/linux/CMakeLists.txt
new file mode 100644
index 000000000000..854d45f2ee97
--- /dev/null
+++ b/libc/src/stdlib/linux/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_entrypoint_object(
+ _Exit
+ SRCS
+ _Exit.cpp
+ HDRS
+ ../_Exit.h
+ DEPENDS
+ sys_syscall_h
+ linux_syscall_h
+ stdlib_h
+)
diff --git a/libc/src/stdlib/linux/_Exit.cpp b/libc/src/stdlib/linux/_Exit.cpp
new file mode 100644
index 000000000000..1c5f60a17a27
--- /dev/null
+++ b/libc/src/stdlib/linux/_Exit.cpp
@@ -0,0 +1,24 @@
+//===------------------- 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
diff --git a/libc/test/src/CMakeLists.txt b/libc/test/src/CMakeLists.txt
index bc698a64fa7d..bf56591e1d47 100644
--- a/libc/test/src/CMakeLists.txt
+++ b/libc/test/src/CMakeLists.txt
@@ -1,4 +1,5 @@
add_subdirectory(errno)
add_subdirectory(signal)
+add_subdirectory(stdlib)
add_subdirectory(string)
add_subdirectory(sys)
diff --git a/libc/test/src/stdlib/CMakeLists.txt b/libc/test/src/stdlib/CMakeLists.txt
new file mode 100644
index 000000000000..6588d457e9a9
--- /dev/null
+++ b/libc/test/src/stdlib/CMakeLists.txt
@@ -0,0 +1,26 @@
+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
+)
diff --git a/libc/test/src/stdlib/_Exit_test.cpp b/libc/test/src/stdlib/_Exit_test.cpp
new file mode 100644
index 000000000000..49878bfd506e
--- /dev/null
+++ b/libc/test/src/stdlib/_Exit_test.cpp
@@ -0,0 +1,16 @@
+//===----------------------- 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);
+}
diff --git a/libc/test/src/stdlib/abort_test.cpp b/libc/test/src/stdlib/abort_test.cpp
new file mode 100644
index 000000000000..cefb5d803687
--- /dev/null
+++ b/libc/test/src/stdlib/abort_test.cpp
@@ -0,0 +1,18 @@
+//===----------------------- 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);
+}
More information about the libc-commits
mailing list