diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt index fbdf8fb621b0f..39b4f9319b956 100644 --- a/libc/config/linux/aarch64/entrypoints.txt +++ b/libc/config/linux/aarch64/entrypoints.txt @@ -970,6 +970,7 @@ if(LLVM_LIBC_FULL_BUILD) libc.src.stdio.fileno libc.src.stdio.flockfile libc.src.stdio.fopen + libc.src.stdio.fopen_s libc.src.stdio.fopencookie libc.src.stdio.fputc libc.src.stdio.fputs @@ -1000,11 +1001,14 @@ if(LLVM_LIBC_FULL_BUILD) # stdlib.h entrypoints libc.src.stdlib._Exit libc.src.stdlib.abort + libc.src.stdlib.abort_handler_s libc.src.stdlib.at_quick_exit libc.src.stdlib.atexit libc.src.stdlib.exit libc.src.stdlib.getenv + libc.src.stdlib.ignore_handler_s libc.src.stdlib.quick_exit + libc.src.stdlib.set_constraint_handler_s # signal.h entrypoints libc.src.signal.kill diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt index ba67dddbe8b98..0210cd9ddee5e 100644 --- a/libc/config/linux/riscv/entrypoints.txt +++ b/libc/config/linux/riscv/entrypoints.txt @@ -1096,6 +1096,7 @@ if(LLVM_LIBC_FULL_BUILD) libc.src.stdio.fileno libc.src.stdio.flockfile libc.src.stdio.fopen + libc.src.stdio.fopen_s libc.src.stdio.fopencookie libc.src.stdio.fputc libc.src.stdio.fputs @@ -1126,11 +1127,14 @@ if(LLVM_LIBC_FULL_BUILD) # stdlib.h entrypoints libc.src.stdlib._Exit libc.src.stdlib.abort + libc.src.stdlib.abort_handler_s libc.src.stdlib.at_quick_exit libc.src.stdlib.atexit libc.src.stdlib.exit libc.src.stdlib.getenv + libc.src.stdlib.ignore_handler_s libc.src.stdlib.quick_exit + libc.src.stdlib.set_constraint_handler_s # signal.h entrypoints libc.src.signal.kill diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index 066dc21497691..78d95a3b57708 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -1131,6 +1131,7 @@ if(LLVM_LIBC_FULL_BUILD) libc.src.stdio.fileno libc.src.stdio.flockfile libc.src.stdio.fopen + libc.src.stdio.fopen_s libc.src.stdio.fopencookie libc.src.stdio.fputc libc.src.stdio.fputs @@ -1161,11 +1162,14 @@ if(LLVM_LIBC_FULL_BUILD) # stdlib.h entrypoints libc.src.stdlib._Exit libc.src.stdlib.abort + libc.src.stdlib.abort_handler_s libc.src.stdlib.at_quick_exit libc.src.stdlib.atexit libc.src.stdlib.exit libc.src.stdlib.getenv + libc.src.stdlib.ignore_handler_s libc.src.stdlib.quick_exit + libc.src.stdlib.set_constraint_handler_s # signal.h entrypoints libc.src.signal.kill diff --git a/libc/hdr/types/CMakeLists.txt b/libc/hdr/types/CMakeLists.txt index 02fe1adc264fb..6cd39d0dca020 100644 --- a/libc/hdr/types/CMakeLists.txt +++ b/libc/hdr/types/CMakeLists.txt @@ -162,6 +162,24 @@ add_proxy_header_library( libc.include.fcntl ) +add_proxy_header_library( + errno_t + HDRS + errno_t.h + FULL_BUILD_DEPENDS + libc.include.llvm-libc-types.errno_t + libc.include.errno +) + +add_proxy_header_library( + constraint_handler_t + HDRS + constraint_handler_t.h + FULL_BUILD_DEPENDS + libc.include.llvm-libc-types.constraint_handler_t + libc.include.stdlib +) + add_proxy_header_library( fenv_t HDRS diff --git a/libc/hdr/types/constraint_handler_t.h b/libc/hdr/types/constraint_handler_t.h new file mode 100644 index 0000000000000..ca7798b84228e --- /dev/null +++ b/libc/hdr/types/constraint_handler_t.h @@ -0,0 +1,18 @@ +//===-- Proxy for constraint_handler_t ------------------------------------===// +// +// 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_HDR_TYPES_CONSTRAINT_HANDLER_T_H +#define LLVM_LIBC_HDR_TYPES_CONSTRAINT_HANDLER_T_H + +#define LIBC_HAS_ANNEX_K + +#include "include/llvm-libc-types/constraint_handler_t.h" + +#undef LIBC_HAS_ANNEX_K + +#endif // LLVM_LIBC_HDR_TYPES_CONSTRAINT_HANDLER_T_H diff --git a/libc/hdr/types/errno_t.h b/libc/hdr/types/errno_t.h new file mode 100644 index 0000000000000..91706b05c9155 --- /dev/null +++ b/libc/hdr/types/errno_t.h @@ -0,0 +1,18 @@ +//===-- Proxy for errno_t -------------------------------------------------===// +// +// 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_HDR_TYPES_ERRNO_T_H +#define LLVM_LIBC_HDR_TYPES_ERRNO_T_H + +#define LIBC_HAS_ANNEX_K + +#include "include/llvm-libc-types/errno_t.h" + +#undef LIBC_HAS_ANNEX_K + +#endif // LLVM_LIBC_HDR_TYPES_ERRNO_T_H diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt index 74fcea0f15e2f..ac7fcbdfe5854 100644 --- a/libc/include/CMakeLists.txt +++ b/libc/include/CMakeLists.txt @@ -290,6 +290,7 @@ add_header_macro( DEPENDS .llvm-libc-macros.generic_error_number_macros .llvm-libc-macros.error_number_macros + .llvm-libc-types.errno_t ) add_header_macro( @@ -331,6 +332,7 @@ add_header_macro( ../libc/include/stdio.yaml stdio.h DEPENDS + .llvm-libc-macros.annex_k_macros .llvm-libc-macros.file_seek_macros .llvm-libc-macros.null_macro .llvm-libc-macros.stdio_macros @@ -339,6 +341,7 @@ add_header_macro( .llvm-libc-types.off_t .llvm-libc-types.size_t .llvm-libc-types.ssize_t + .llvm-libc-types.errno_t .llvm_libc_common_h ) @@ -358,6 +361,8 @@ add_header_macro( .llvm-libc-types.lldiv_t .llvm-libc-types.locale_t .llvm-libc-types.size_t + .llvm-libc-types.rsize_t + .llvm-libc-types.constraint_handler_t .llvm_libc_common_h ) diff --git a/libc/include/errno.h.def b/libc/include/errno.h.def index aa1f6c9e48444..35341c60e38b2 100644 --- a/libc/include/errno.h.def +++ b/libc/include/errno.h.def @@ -33,4 +33,6 @@ __END_C_DECLS #define errno (*__llvm_libc_errno()) +#include "llvm-libc-types/errno_t.h" + #endif // LLVM_LIBC_ERRNO_H diff --git a/libc/include/llvm-libc-macros/CMakeLists.txt b/libc/include/llvm-libc-macros/CMakeLists.txt index 7aa549ddc75d9..30699c7e43ac8 100644 --- a/libc/include/llvm-libc-macros/CMakeLists.txt +++ b/libc/include/llvm-libc-macros/CMakeLists.txt @@ -31,6 +31,12 @@ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS}) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS}) endif() +add_macro_header( + annex_k_macros + HDR + annex-k-macros.h +) + add_macro_header( assert_macros HDR diff --git a/libc/include/llvm-libc-macros/annex-k-macros.h b/libc/include/llvm-libc-macros/annex-k-macros.h new file mode 100644 index 0000000000000..75e1fd52d1257 --- /dev/null +++ b/libc/include/llvm-libc-macros/annex-k-macros.h @@ -0,0 +1,25 @@ +//===-- Definition of macros to be used with Annex K functions ------------===// +// +// 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_INCLUDE_LLVM_LIBC_MACROS_ANNEX_K_MACROS_H +#define LLVM_LIBC_INCLUDE_LLVM_LIBC_MACROS_ANNEX_K_MACROS_H + +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || \ + (defined(__cplusplus) && __cplusplus >= 201703L) + +#define __STDC_LIB_EXT1__ 200509L + +#if defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ == 1 + +#define LIBC_HAS_ANNEX_K + +#endif // defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ == 1 + +#endif // (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || + // (defined(__cplusplus) && __cplusplus >= 201703L) +#endif // LLVM_LIBC_INCLUDE_LLVM_LIBC_MACROS_ANNEX_K_MACROS_H diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt index 451beae6f1e6f..6480491f6ea4c 100644 --- a/libc/include/llvm-libc-types/CMakeLists.txt +++ b/libc/include/llvm-libc-types/CMakeLists.txt @@ -1,5 +1,6 @@ add_header(off64_t HDR off64_t.h) add_header(size_t HDR size_t.h) +add_header(rsize_t HDR rsize_t.h) add_header(ssize_t HDR ssize_t.h) add_header(__atfork_callback_t HDR __atfork_callback_t.h) add_header(__search_compare_t HDR __search_compare_t.h) @@ -289,3 +290,7 @@ add_header(EFI_SYSTEM_TABLE .EFI_TABLE_HEADER .char16_t ) + +add_header(errno_t HDR errno_t.h) + +add_header(constraint_handler_t HDR constraint_handler_t.h DEPENDS .errno_t) diff --git a/libc/include/llvm-libc-types/constraint_handler_t.h b/libc/include/llvm-libc-types/constraint_handler_t.h new file mode 100644 index 0000000000000..efd21296cd399 --- /dev/null +++ b/libc/include/llvm-libc-types/constraint_handler_t.h @@ -0,0 +1,21 @@ +//===-- Definition of type constraint_handler_t ---------------------------===// +// +// 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_INCLUDE_LLVM_LIBC_TYPES_CONSTRAINT_HANDLER_T_H +#define LLVM_LIBC_INCLUDE_LLVM_LIBC_TYPES_CONSTRAINT_HANDLER_T_H + +#include "errno_t.h" + +#ifdef LIBC_HAS_ANNEX_K + +typedef void (*constraint_handler_t)(const char *__restrict, void *__restrict, + errno_t); + +#endif // LIBC_HAS_ANNEX_K + +#endif // LLVM_LIBC_INCLUDE_LLVM_LIBC_TYPES_CONSTRAINT_HANDLER_T_H diff --git a/libc/include/llvm-libc-types/errno_t.h b/libc/include/llvm-libc-types/errno_t.h new file mode 100644 index 0000000000000..f99fe1266ccd1 --- /dev/null +++ b/libc/include/llvm-libc-types/errno_t.h @@ -0,0 +1,18 @@ +//===-- Definition of type errno_t ----------------------------------------===// +// +// 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_INCLUDE_LLVM_LIBC_TYPES_ERRNO_T_H +#define LLVM_LIBC_INCLUDE_LLVM_LIBC_TYPES_ERRNO_T_H + +#ifdef LIBC_HAS_ANNEX_K + +typedef int errno_t; + +#endif // LIBC_HAS_ANNEX_K + +#endif // LLVM_LIBC_INCLUDE_LLVM_LIBC_TYPES_ERRNO_T_H diff --git a/libc/include/llvm-libc-types/rsize_t.h b/libc/include/llvm-libc-types/rsize_t.h new file mode 100644 index 0000000000000..52f61d4a61091 --- /dev/null +++ b/libc/include/llvm-libc-types/rsize_t.h @@ -0,0 +1,18 @@ +//===-- Definition of rsize_t types ---------------------------------------===// +// +// 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_TYPES_RSIZE_T_H +#define LLVM_LIBC_TYPES_RSIZE_T_H + +#ifdef LIBC_HAS_ANNEX_K + +typedef __SIZE_TYPE__ rsize_t; + +#endif // LIBC_HAS_ANNEX_K + +#endif // LLVM_LIBC_TYPES_RSIZE_T_H diff --git a/libc/include/stdio.yaml b/libc/include/stdio.yaml index 2a0c563709984..1a0d2ecd9a57d 100644 --- a/libc/include/stdio.yaml +++ b/libc/include/stdio.yaml @@ -9,8 +9,11 @@ macros: macro_value: stdin - macro_name: stderr macro_value: stderr + - macro_name: LIBC_HAS_ANNEX_K + macro_header: annex-k-macros.h types: - type_name: size_t + - type_name: errno_t - type_name: off_t - type_name: cookie_io_functions_t - type_name: FILE @@ -125,6 +128,15 @@ functions: arguments: - type: const char * - type: const char * + - name: fopen_s + guard: LIBC_HAS_ANNEX_K + standards: + - stdc + return_type: errno_t + arguments: + - type: FILE *__restrict *__restrict + - type: const char *__restrict + - type: const char *__restrict - name: fopencookie standards: - GNUExtensions diff --git a/libc/include/stdlib.yaml b/libc/include/stdlib.yaml index 3b2ff13c684b1..531d01197e656 100644 --- a/libc/include/stdlib.yaml +++ b/libc/include/stdlib.yaml @@ -5,7 +5,9 @@ standards: merge_yaml_files: - stdlib-malloc.yaml macros: - - macro_name: NULL + - macro_name: 'LIBC_HAS_ANNEX_K' + macro_header: annex-k-macros.h + - macro_name: 'NULL' macro_header: null-macro.h types: - type_name: __atexithandler_t @@ -17,6 +19,9 @@ types: - type_name: lldiv_t - type_name: locale_t - type_name: size_t + - type_name: rsize_t + - type_name: errno_t + - type_name: constraint_handler_t enums: [] objects: [] functions: @@ -180,6 +185,31 @@ functions: return_type: int arguments: - type: void + - name: set_constraint_handler_s + standards: + - stdc + return_type: constraint_handler_t + arguments: + - type: constraint_handler_t + guard: 'LIBC_HAS_ANNEX_K' + - name: abort_handler_s + standards: + - stdc + return_type: void + arguments: + - type: const char *__restrict + - type: void *__restrict + - type: errno_t + guard: 'LIBC_HAS_ANNEX_K' + - name: ignore_handler_s + standards: + - stdc + return_type: void + arguments: + - type: const char *__restrict + - type: void *__restrict + - type: errno_t + guard: 'LIBC_HAS_ANNEX_K' - name: srand standards: - stdc diff --git a/libc/src/stdio/CMakeLists.txt b/libc/src/stdio/CMakeLists.txt index b0a6ef1e291b5..9bc51c27d8d8a 100644 --- a/libc/src/stdio/CMakeLists.txt +++ b/libc/src/stdio/CMakeLists.txt @@ -218,6 +218,7 @@ add_stdio_entrypoint_object(fflush) add_stdio_entrypoint_object(clearerr) add_stdio_entrypoint_object(clearerr_unlocked) add_stdio_entrypoint_object(fopen) +add_stdio_entrypoint_object(fopen_s) add_stdio_entrypoint_object(fclose) add_stdio_entrypoint_object(fread_unlocked) add_stdio_entrypoint_object(fread) diff --git a/libc/src/stdio/fopen_s.h b/libc/src/stdio/fopen_s.h new file mode 100644 index 0000000000000..36a4445f9309e --- /dev/null +++ b/libc/src/stdio/fopen_s.h @@ -0,0 +1,23 @@ +//===-- Implementation header of fopen_s ------------------------*- 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_STDIO_FOPEN_S_H +#define LLVM_LIBC_SRC_STDIO_FOPEN_S_H + +#include "hdr/types/FILE.h" +#include "hdr/types/errno_t.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +errno_t fopen_s(FILE *__restrict *__restrict streamptr, + const char *__restrict filename, const char *__restrict mode); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_STDIO_FOPEN_S_H diff --git a/libc/src/stdio/generic/CMakeLists.txt b/libc/src/stdio/generic/CMakeLists.txt index 6361822b61999..1c54890df0bce 100644 --- a/libc/src/stdio/generic/CMakeLists.txt +++ b/libc/src/stdio/generic/CMakeLists.txt @@ -167,6 +167,18 @@ add_generic_entrypoint_object( libc.src.__support.File.platform_file ) +add_generic_entrypoint_object( + fopen_s + SRCS + fopen_s.cpp + HDRS + ../fopen_s.h + DEPENDS + libc.src.stdio.fopen + libc.src.__support.macros.config + libc.src.stdlib.annex_k_helper_macros +) + add_generic_entrypoint_object( fclose SRCS diff --git a/libc/src/stdio/generic/fopen_s.cpp b/libc/src/stdio/generic/fopen_s.cpp new file mode 100644 index 0000000000000..8a60a3ce624cc --- /dev/null +++ b/libc/src/stdio/generic/fopen_s.cpp @@ -0,0 +1,44 @@ +//===-- Implementation of fopen_s -----------------------------------------===// +// +// 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/stdio/fopen_s.h" +#include "src/__support/macros/config.h" +#include "src/stdio/fopen.h" +#include "src/stdlib/annex_k_helper_macros.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(errno_t, fopen_s, + (FILE *__restrict *__restrict streamptr, + const char *__restrict filename, + const char *__restrict mode)) { + _CONSTRAINT_VIOLATION_IF(streamptr == 0, EINVAL, EINVAL); + _CONSTRAINT_VIOLATION_CLEANUP_IF(!mode || !filename, *streamptr = nullptr, + EINVAL, EINVAL); + + FILE *ret = nullptr; + + if (mode[0] == 'u') { + ret = fopen(filename, mode + 1); + if (!ret) { + *streamptr = nullptr; + return -1; + } + } else { + ret = fopen(filename, mode); + if (!ret) { + *streamptr = nullptr; + return -1; + } + } + + *streamptr = ret; + return 0; +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/stdlib/CMakeLists.txt b/libc/src/stdlib/CMakeLists.txt index aa653c38a8c3f..fb6f3dec1d582 100644 --- a/libc/src/stdlib/CMakeLists.txt +++ b/libc/src/stdlib/CMakeLists.txt @@ -652,3 +652,64 @@ add_entrypoint_object( DEPENDS .${LIBC_TARGET_OS}.system ) + +add_header_library( + annex_k_helper_macros + HDRS + annex_k_helper_macros.h + DEPENDS + .annex_k_libc_constraint_handler + libc.src.__support.libc_errno +) + +add_header_library( + annex_k_libc_constraint_handler + HDRS + annex_k_libc_constraint_handler.h + DEPENDS + .abort_handler_s + libc.hdr.types.constraint_handler_t + libc.src.__support.common +) + +add_entrypoint_object( + set_constraint_handler_s + SRCS + set_constraint_handler_s.cpp + HDRS + set_constraint_handler_s.h + DEPENDS + .abort_handler_s + .annex_k_libc_constraint_handler + libc.src.__support.macros.config +) + +add_entrypoint_object( + abort_handler_s + SRCS + abort_handler_s.cpp + HDRS + abort_handler_s.h + DEPENDS + libc.hdr.stdio_macros + libc.hdr.types.errno_t + libc.src.__support.macros.config + libc.src.__support.macros.attributes + libc.src.__support.File.file + libc.src.stdio.fflush + libc.src.stdio.fprintf + libc.src.stdlib.abort +) + +add_entrypoint_object( + ignore_handler_s + HDRS + ignore_handler_s.h + SRCS + ignore_handler_s.cpp + DEPENDS + libc.hdr.types.errno_t + libc.src.__support.libc_errno + libc.src.__support.macros.config + libc.src.__support.macros.attributes +) diff --git a/libc/src/stdlib/abort_handler_s.cpp b/libc/src/stdlib/abort_handler_s.cpp new file mode 100644 index 0000000000000..b34aaa1197257 --- /dev/null +++ b/libc/src/stdlib/abort_handler_s.cpp @@ -0,0 +1,38 @@ +//===-- Implementation for abort_handler_s ----------------------*- 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 +// +//===----------------------------------------------------------------------===// + +#include "src/stdlib/abort_handler_s.h" +#include "hdr/stdio_macros.h" +#include "hdr/types/errno_t.h" +#include "src/__support/common.h" +#include "src/__support/libc_errno.h" +#include "src/stdio/fflush.h" +#include "src/stdio/fprintf.h" +#include "src/stdlib/abort.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(void, abort_handler_s, + (const char *__restrict msg, + [[maybe_unused]] void *__restrict ptr, errno_t error)) { + libc_errno = error; + fprintf(stderr, "abort_handler_s was called in response to a " + "runtime-constraint violation.\n\n"); + if (msg) + fprintf(stderr, "%s\n", msg); + fprintf(stderr, + "\n\nNote to end users: This program was terminated as a result\ + of a bug present in the software. Please reach out to your \ + software's vendor to get more help.\n"); + + fflush(stderr); + + abort(); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/stdlib/abort_handler_s.h b/libc/src/stdlib/abort_handler_s.h new file mode 100644 index 0000000000000..b97a081b036d2 --- /dev/null +++ b/libc/src/stdlib/abort_handler_s.h @@ -0,0 +1,22 @@ +//===-- Implementation header for abort_handler_s ---------------*- 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_ABORT_HANDLER_S_H +#define LLVM_LIBC_SRC_STDLIB_ABORT_HANDLER_S_H + +#include "hdr/types/errno_t.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +void abort_handler_s(const char *__restrict msg, void *__restrict ptr, + errno_t error); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_STDLIB_ABORT_HANDLER_S_H diff --git a/libc/src/stdlib/annex_k_helper_macros.h b/libc/src/stdlib/annex_k_helper_macros.h new file mode 100644 index 0000000000000..b21fbe04535b5 --- /dev/null +++ b/libc/src/stdlib/annex_k_helper_macros.h @@ -0,0 +1,44 @@ +//===-- Helper macros header for constraint violations ----------*- 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_ANNEX_K_HELPER_MACROS_H +#define LLVM_LIBC_SRC_STDLIB_ANNEX_K_HELPER_MACROS_H + +#include "annex_k_libc_constraint_handler.h" +#include "src/__support/libc_errno.h" + +#define _CONSTRAINT_VIOLATION(msg, error_code, ret_code) \ + { \ + libc_errno = error_code; \ + libc_constraint_handler(msg, nullptr, error_code); \ + return ret_code; \ + } + +#define _CONSTRAINT_VIOLATION_IF(expr, error_code, return_code) \ + { \ + auto expr_val = expr; \ + if (expr_val) { \ + libc_errno = error_code; \ + libc_constraint_handler(nullptr, nullptr, error_code); \ + return return_code; \ + } \ + } + +#define _CONSTRAINT_VIOLATION_CLEANUP_IF(expr, cleanup, error_code, \ + return_code) \ + { \ + auto expr_val = expr; \ + if (expr_val) { \ + cleanup; \ + libc_errno = error_code; \ + libc_constraint_handler(nullptr, nullptr, error_code); \ + return return_code; \ + } \ + } + +#endif // LLVM_LIBC_SRC_STDLIB_ANNEX_K_HELPER_MACROS_H diff --git a/libc/src/stdlib/annex_k_libc_constraint_handler.h b/libc/src/stdlib/annex_k_libc_constraint_handler.h new file mode 100644 index 0000000000000..abaf0cd0967ef --- /dev/null +++ b/libc/src/stdlib/annex_k_libc_constraint_handler.h @@ -0,0 +1,23 @@ +//===-- Static header for libc_constraint_handler ---------------*- 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_ANNEX_K_LIBC_CONSTRAINT_HANDLER_H +#define LLVM_LIBC_SRC_STDLIB_ANNEX_K_LIBC_CONSTRAINT_HANDLER_H + +#include "hdr/types/constraint_handler_t.h" +#include "src/__support/common.h" +#include "src/stdlib/abort_handler_s.h" + +namespace LIBC_NAMESPACE_DECL { + +LIBC_INLINE static constraint_handler_t libc_constraint_handler = + &abort_handler_s; + +} + +#endif // LLVM_LIBC_SRC_STDLIB_ANNEX_K_LIBC_CONSTRAINT_HANDLER_H diff --git a/libc/src/stdlib/ignore_handler_s.cpp b/libc/src/stdlib/ignore_handler_s.cpp new file mode 100644 index 0000000000000..172b1bcdb7b30 --- /dev/null +++ b/libc/src/stdlib/ignore_handler_s.cpp @@ -0,0 +1,16 @@ +//===-- Implementation header for ignore_handler_s --------------*- 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 +// +//===----------------------------------------------------------------------===// + +#include "src/stdlib/ignore_handler_s.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(void, ignore_handler_s, + (const char *__restrict, void *__restrict, errno_t)) {} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/stdlib/ignore_handler_s.h b/libc/src/stdlib/ignore_handler_s.h new file mode 100644 index 0000000000000..07328d4be01ce --- /dev/null +++ b/libc/src/stdlib/ignore_handler_s.h @@ -0,0 +1,22 @@ +//===-- Implementation header for ignore_handler_s --------------*- 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_IGNORE_HANDLER_S_H +#define LLVM_LIBC_SRC_STDLIB_IGNORE_HANDLER_S_H + +#include "hdr/types/errno_t.h" +#include "src/__support/common.h" + +namespace LIBC_NAMESPACE_DECL { + +void ignore_handler_s(const char *__restrict msg, void *__restrict ptr, + errno_t error); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_STDLIB_IGNORE_HANDLER_S_H diff --git a/libc/src/stdlib/set_constraint_handler_s.cpp b/libc/src/stdlib/set_constraint_handler_s.cpp new file mode 100644 index 0000000000000..18b5d24fda6a0 --- /dev/null +++ b/libc/src/stdlib/set_constraint_handler_s.cpp @@ -0,0 +1,29 @@ +//===-- Implementation of set_constraint_handler_s ------------------------===// +// +// 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 "set_constraint_handler_s.h" +#include "abort_handler_s.h" +#include "annex_k_libc_constraint_handler.h" +#include "src/__support/common.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(constraint_handler_t, set_constraint_handler_s, + (constraint_handler_t handler)) { + constraint_handler_t previous_handler = libc_constraint_handler; + + if (!handler) { + libc_constraint_handler = &abort_handler_s; + } else { + libc_constraint_handler = handler; + } + + return previous_handler; +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/stdlib/set_constraint_handler_s.h b/libc/src/stdlib/set_constraint_handler_s.h new file mode 100644 index 0000000000000..f5c6e01712ef0 --- /dev/null +++ b/libc/src/stdlib/set_constraint_handler_s.h @@ -0,0 +1,21 @@ +//===-- Implementation header for set_constraint_handler_s ------*- 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_SET_CONSTRAINT_HANDLER_S_H +#define LLVM_LIBC_SRC_STDLIB_SET_CONSTRAINT_HANDLER_S_H + +#include "hdr/types/constraint_handler_t.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +constraint_handler_t set_constraint_handler_s(constraint_handler_t handler); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_STDLIB_SET_CONSTRAINT_HANDLER_S_H