aboutsummaryrefslogtreecommitdiff
path: root/libc/startup
diff options
context:
space:
mode:
Diffstat (limited to 'libc/startup')
-rw-r--r--libc/startup/baremetal/CMakeLists.txt64
-rw-r--r--libc/startup/baremetal/arm/CMakeLists.txt16
-rw-r--r--libc/startup/baremetal/arm/start.cpp92
-rw-r--r--libc/startup/baremetal/fini.cpp8
-rw-r--r--libc/startup/baremetal/fini.h16
-rw-r--r--libc/startup/baremetal/init.cpp10
-rw-r--r--libc/startup/baremetal/init.h18
-rw-r--r--libc/startup/linux/CMakeLists.txt1
-rw-r--r--libc/startup/linux/do_start.cpp2
9 files changed, 212 insertions, 15 deletions
diff --git a/libc/startup/baremetal/CMakeLists.txt b/libc/startup/baremetal/CMakeLists.txt
index 4faced9..e361000 100644
--- a/libc/startup/baremetal/CMakeLists.txt
+++ b/libc/startup/baremetal/CMakeLists.txt
@@ -1,11 +1,75 @@
+# TODO: Use generic "add_startup_object" https://github.com/llvm/llvm-project/issues/133156
+function(add_startup_object name)
+ cmake_parse_arguments(
+ "ADD_STARTUP_OBJECT"
+ "ALIAS" # Option argument
+ "SRC" # Single value arguments
+ "DEPENDS;COMPILE_OPTIONS" # Multi value arguments
+ ${ARGN}
+ )
+
+ get_fq_target_name(${name} fq_target_name)
+ if(ADD_STARTUP_OBJECT_ALIAS)
+ get_fq_deps_list(fq_dep_list ${ADD_STARTUP_OBJECT_DEPENDS})
+ add_library(${fq_target_name} ALIAS ${fq_dep_list})
+ return()
+ endif()
+
+ add_object_library(
+ ${name}
+ SRCS ${ADD_STARTUP_OBJECT_SRC}
+ COMPILE_OPTIONS ${ADD_STARTUP_OBJECT_COMPILE_OPTIONS}
+ ${ADD_STARTUP_OBJECT_UNPARSED_ARGUMENTS}
+ DEPENDS ${ADD_STARTUP_OBJECT_DEPENDS}
+ )
+ set_target_properties(
+ ${fq_target_name}
+ PROPERTIES
+ OUTPUT_NAME ${name}.o
+ )
+endfunction()
+
add_entrypoint_object(
init
SRCS
init.cpp
+ DEPENDS
+ libc.hdr.stdint_proxy
+ libc.src.__support.common
+ HDRS
+ init.h
)
add_entrypoint_object(
fini
SRCS
fini.cpp
+ DEPENDS
+ libc.hdr.stdint_proxy
+ libc.src.__support.common
+ HDRS
+ fini.h
+)
+
+if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_ARCHITECTURE})
+ add_subdirectory(${LIBC_TARGET_ARCHITECTURE})
+else()
+ message(WARNING "Cannot build 'crt1.o' for ${LIBC_TARGET_ARCHITECTURE} yet.")
+ return()
+endif()
+
+add_startup_object(
+ crt1
+ ALIAS
+ DEPENDS
+ .${LIBC_TARGET_ARCHITECTURE}.crt1
)
+
+add_custom_target(libc-startup)
+
+set(fq_target_name libc.startup.baremetal.${LIBC_TARGET_ARCHITECTURE}.crt1)
+add_dependencies(libc-startup ${fq_target_name})
+install(FILES $<TARGET_OBJECTS:${fq_target_name}>
+ DESTINATION ${LIBC_INSTALL_LIBRARY_DIR}
+ RENAME $<TARGET_PROPERTY:${fq_target_name},OUTPUT_NAME>
+ COMPONENT libc)
diff --git a/libc/startup/baremetal/arm/CMakeLists.txt b/libc/startup/baremetal/arm/CMakeLists.txt
new file mode 100644
index 0000000..f75bd89
--- /dev/null
+++ b/libc/startup/baremetal/arm/CMakeLists.txt
@@ -0,0 +1,16 @@
+add_startup_object(
+ crt1
+ SRC
+ start.cpp
+ DEPENDS
+ libc.src.stdlib.atexit
+ libc.src.stdlib.exit
+ libc.src.string.memcpy
+ libc.src.string.memset
+ libc.startup.baremetal.init
+ libc.startup.baremetal.fini
+ COMPILE_OPTIONS
+ -ffreestanding # To avoid compiler warnings about calling the main function.
+ -fno-builtin
+ -Wno-global-constructors # To allow vector table initialization
+)
diff --git a/libc/startup/baremetal/arm/start.cpp b/libc/startup/baremetal/arm/start.cpp
new file mode 100644
index 0000000..123efc4
--- /dev/null
+++ b/libc/startup/baremetal/arm/start.cpp
@@ -0,0 +1,92 @@
+//===-- Implementation of crt for arm -------------------------------------===//
+//
+// 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/macros/config.h"
+#include "src/stdlib/atexit.h"
+#include "src/stdlib/exit.h"
+#include "src/string/memcpy.h"
+#include "src/string/memset.h"
+#include "startup/baremetal/fini.h"
+#include "startup/baremetal/init.h"
+
+#include <stdint.h>
+
+extern "C" {
+int main(int argc, char **argv);
+void _start();
+
+// Semihosting library initialisation if applicable. Required for printf, etc.
+[[gnu::weak]] void _platform_init() {}
+
+// These symbols are provided by the linker. The exact names are not defined by
+// a standard.
+extern uintptr_t __stack;
+extern uintptr_t __data_source[];
+extern uintptr_t __data_start[];
+extern uintptr_t __data_size[];
+extern uintptr_t __bss_start[];
+extern uintptr_t __bss_size[];
+
+// Based on
+// https://developer.arm.com/documentation/107565/0101/Use-case-examples/Generic-Information/What-is-inside-a-program-image-/Vector-table
+void NMI_Handler() {}
+void HardFault_Handler() { LIBC_NAMESPACE::exit(1); }
+void MemManage_Handler() { LIBC_NAMESPACE::exit(1); }
+void BusFault_Handler() { LIBC_NAMESPACE::exit(1); }
+void UsageFault_Handler() { LIBC_NAMESPACE::exit(1); }
+void SVC_Handler() {}
+void DebugMon_Handler() {}
+void PendSV_Handler() {}
+void SysTick_Handler() {}
+
+// Architecturally the bottom 7 bits of VTOR are zero, meaning the vector table
+// has to be 128-byte aligned, however an implementation can require more bits
+// to be zero and Cortex-M23 can require up to 10, so 1024-byte align the vector
+// table.
+using HandlerType = void (*)(void);
+const HandlerType vector_table[]
+ __attribute__((section(".vectors"), aligned(1024), used)) = {
+ (HandlerType)&__stack, // SP
+ _start, // Reset
+ NMI_Handler, // NMI Handler
+ HardFault_Handler, // Hard Fault Handlerß
+ MemManage_Handler, // MPU Fault Han`dler
+ BusFault_Handler, // Bus Fault Handler
+ UsageFault_Handler, // Usage Fault Handler
+ 0, // Reserved
+ 0, // Reserved
+ 0, // Reserved
+ 0, // Reserved
+ SVC_Handler, // SVC Handler
+ DebugMon_Handler, // Debug Monitor Handler
+ 0, // Reserved
+ PendSV_Handler, // PendSV Handler
+ SysTick_Handler, // SysTick Handler
+ // Unused
+};
+} // extern "C"
+
+namespace LIBC_NAMESPACE_DECL {
+[[noreturn]] void do_start() {
+ // FIXME: set up the QEMU test environment
+
+ // Perform the equivalent of scatterloading
+ LIBC_NAMESPACE::memcpy(__data_start, __data_source, (uintptr_t)__data_size);
+ LIBC_NAMESPACE::memset(__bss_start, '\0', (uintptr_t)__bss_size);
+ __libc_init_array();
+
+ _platform_init();
+ LIBC_NAMESPACE::atexit(&__libc_fini_array);
+ LIBC_NAMESPACE::exit(main(0, 0));
+}
+} // namespace LIBC_NAMESPACE_DECL
+
+extern "C" void _start() {
+ asm volatile("mov sp, %0" : : "r"(&__stack));
+ asm volatile("bl %0" : : "X"(LIBC_NAMESPACE::do_start));
+}
diff --git a/libc/startup/baremetal/fini.cpp b/libc/startup/baremetal/fini.cpp
index 263d7192..66714e2 100644
--- a/libc/startup/baremetal/fini.cpp
+++ b/libc/startup/baremetal/fini.cpp
@@ -6,17 +6,13 @@
//
//===----------------------------------------------------------------------===//
+#include "startup/baremetal/fini.h"
+
#include "src/__support/macros/config.h"
#include <stddef.h>
-#include <stdint.h>
namespace LIBC_NAMESPACE_DECL {
-extern "C" {
-extern uintptr_t __fini_array_start[];
-extern uintptr_t __fini_array_end[];
-}
-
using FiniCallback = void(void);
extern "C" void __libc_fini_array(void) {
diff --git a/libc/startup/baremetal/fini.h b/libc/startup/baremetal/fini.h
new file mode 100644
index 0000000..74e9601
--- /dev/null
+++ b/libc/startup/baremetal/fini.h
@@ -0,0 +1,16 @@
+//===-- Implementation header 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 "hdr/stdint_proxy.h"
+
+extern "C" {
+extern uintptr_t __fini_array_start[];
+extern uintptr_t __fini_array_end[];
+
+void __libc_fini_array(void);
+} // extern "C"
diff --git a/libc/startup/baremetal/init.cpp b/libc/startup/baremetal/init.cpp
index ce38701..89065fd 100644
--- a/libc/startup/baremetal/init.cpp
+++ b/libc/startup/baremetal/init.cpp
@@ -6,19 +6,13 @@
//
//===----------------------------------------------------------------------===//
+#include "startup/baremetal/init.h"
+
#include "src/__support/macros/config.h"
#include <stddef.h>
-#include <stdint.h>
namespace LIBC_NAMESPACE_DECL {
-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[];
-}
-
using InitCallback = void(void);
extern "C" void __libc_init_array(void) {
diff --git a/libc/startup/baremetal/init.h b/libc/startup/baremetal/init.h
new file mode 100644
index 0000000..6b545db3
--- /dev/null
+++ b/libc/startup/baremetal/init.h
@@ -0,0 +1,18 @@
+//===-- Implementation header 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 "hdr/stdint_proxy.h"
+
+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[];
+
+void __libc_init_array(void);
+} // extern "C"
diff --git a/libc/startup/linux/CMakeLists.txt b/libc/startup/linux/CMakeLists.txt
index eaa724e..7af1819 100644
--- a/libc/startup/linux/CMakeLists.txt
+++ b/libc/startup/linux/CMakeLists.txt
@@ -96,6 +96,7 @@ add_object_library(
do_start.h
DEPENDS
libc.config.app_h
+ libc.hdr.stdint_proxy
libc.include.sys_mman
libc.include.sys_syscall
libc.include.llvm-libc-macros.link_macros
diff --git a/libc/startup/linux/do_start.cpp b/libc/startup/linux/do_start.cpp
index ff104c7..94c4ec7 100644
--- a/libc/startup/linux/do_start.cpp
+++ b/libc/startup/linux/do_start.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "startup/linux/do_start.h"
#include "config/linux/app.h"
+#include "hdr/stdint_proxy.h"
#include "include/llvm-libc-macros/link-macros.h"
#include "src/__support/OSUtil/syscall.h"
#include "src/__support/macros/config.h"
@@ -17,7 +18,6 @@
#include <linux/auxvec.h>
#include <linux/elf.h>
-#include <stdint.h>
#include <sys/mman.h>
#include <sys/syscall.h>