[libc] Create abort and _Exit

This revision creates abort and _Exit implementations

Differential Revision: https://reviews.llvm.org/D74949
This commit is contained in:
Alex Brachet 2020-03-05 14:21:18 -05:00
parent ef4282e0ee
commit a499d68056
18 changed files with 231 additions and 0 deletions

View File

@ -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,

View File

@ -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.

View File

@ -17,6 +17,9 @@
#undef __END_C_DECLS
#define __END_C_DECLS }
#undef _Noreturn
#define _Noreturn [[noreturn]]
#else // not __cplusplus
#undef __BEGIN_C_DECLS

16
libc/include/stdlib.h.def Normal file
View File

@ -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

View File

@ -18,6 +18,10 @@ add_entrypoint_library(
sigaddset
sigemptyset
sigprocmask
# stdlib.h entrypoints
_Exit
abort
)
add_entrypoint_library(

View File

@ -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;
}

View File

@ -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,
];

View File

@ -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)

View File

@ -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
)

18
libc/src/stdlib/_Exit.h Normal file
View File

@ -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

30
libc/src/stdlib/abort.cpp Normal file
View File

@ -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

18
libc/src/stdlib/abort.h Normal file
View File

@ -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

View File

@ -0,0 +1,11 @@
add_entrypoint_object(
_Exit
SRCS
_Exit.cpp
HDRS
../_Exit.h
DEPENDS
sys_syscall_h
linux_syscall_h
stdlib_h
)

View File

@ -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

View File

@ -1,4 +1,5 @@
add_subdirectory(errno)
add_subdirectory(signal)
add_subdirectory(stdlib)
add_subdirectory(string)
add_subdirectory(sys)

View File

@ -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
)

View File

@ -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);
}

View File

@ -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);
}