diff --git a/libc/cmake/modules/LLVMLibCObjectRules.cmake b/libc/cmake/modules/LLVMLibCObjectRules.cmake index 0649e9f7a7670..134c5143d6d61 100644 --- a/libc/cmake/modules/LLVMLibCObjectRules.cmake +++ b/libc/cmake/modules/LLVMLibCObjectRules.cmake @@ -246,9 +246,6 @@ function(create_entrypoint_object fq_target_name) if(NOT ADD_ENTRYPOINT_OBJ_SRCS) message(FATAL_ERROR "`add_entrypoint_object` rule requires SRCS to be specified.") endif() - if(NOT ADD_ENTRYPOINT_OBJ_HDRS) - message(FATAL_ERROR "`add_entrypoint_object` rule requires HDRS to be specified.") - endif() if(NOT ADD_ENTRYPOINT_OBJ_CXX_STANDARD) set(ADD_ENTRYPOINT_OBJ_CXX_STANDARD ${CMAKE_CXX_STANDARD}) endif() diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt index 4e3d1cb9f5337..7fb82c60a1bb8 100644 --- a/libc/config/baremetal/arm/entrypoints.txt +++ b/libc/config/baremetal/arm/entrypoints.txt @@ -183,6 +183,10 @@ set(TARGET_LIBC_ENTRYPOINTS # time.h entrypoints libc.src.time.difftime + + # internal entrypoints + libc.startup.baremetal.init + libc.startup.baremetal.fini ) set(TARGET_LIBM_ENTRYPOINTS diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt index 7efd9bcd5b3cb..b769b43f03a2c 100644 --- a/libc/config/baremetal/riscv/entrypoints.txt +++ b/libc/config/baremetal/riscv/entrypoints.txt @@ -183,6 +183,10 @@ set(TARGET_LIBC_ENTRYPOINTS # time.h entrypoints libc.src.time.difftime + + # internal entrypoints + libc.startup.baremetal.init + libc.startup.baremetal.fini ) set(TARGET_LIBM_ENTRYPOINTS diff --git a/libc/startup/baremetal/CMakeLists.txt b/libc/startup/baremetal/CMakeLists.txt new file mode 100644 index 0000000000000..4faced93fabe5 --- /dev/null +++ b/libc/startup/baremetal/CMakeLists.txt @@ -0,0 +1,11 @@ +add_entrypoint_object( + init + SRCS + init.cpp +) + +add_entrypoint_object( + fini + SRCS + fini.cpp +) diff --git a/libc/startup/baremetal/fini.cpp b/libc/startup/baremetal/fini.cpp new file mode 100644 index 0000000000000..84997fb4fa1d8 --- /dev/null +++ b/libc/startup/baremetal/fini.cpp @@ -0,0 +1,27 @@ +//===-- Implementation file of __libc_fini_array --------------------------===// +// +// 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 + +extern "C" { +extern uintptr_t __fini_array_start[]; +extern uintptr_t __fini_array_end[]; +} + +namespace LIBC_NAMESPACE { + +using FiniCallback = void(void); + +extern "C" void __libc_fini_array(void) { + size_t fini_array_size = __fini_array_end - __fini_array_start; + for (size_t i = fini_array_size; i > 0; --i) + reinterpret_cast(__fini_array_start[i - 1])(); +} + +} // namespace LIBC_NAMESPACE diff --git a/libc/startup/baremetal/init.cpp b/libc/startup/baremetal/init.cpp new file mode 100644 index 0000000000000..08dff74f05198 --- /dev/null +++ b/libc/startup/baremetal/init.cpp @@ -0,0 +1,32 @@ +//===-- Implementation file of __libc_init_array --------------------------===// +// +// 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 + +extern "C" { +extern uintptr_t __preinit_array_start[]; +extern uintptr_t __preinit_array_end[]; +extern uintptr_t __init_array_start[]; +extern uintptr_t __init_array_end[]; +} + +namespace LIBC_NAMESPACE { + +using InitCallback = void(void); + +extern "C" void __libc_init_array(void) { + size_t preinit_array_size = __preinit_array_end - __preinit_array_start; + for (size_t i = 0; i < preinit_array_size; ++i) + reinterpret_cast(__preinit_array_start[i])(); + size_t init_array_size = __init_array_end - __init_array_start; + for (size_t i = 0; i < init_array_size; ++i) + reinterpret_cast(__init_array_start[i])(); +} + +} // namespace LIBC_NAMESPACE