diff --git a/arch/xtensa/src/Makefile b/arch/xtensa/src/Makefile index 9308080967567..44de5307bed08 100644 --- a/arch/xtensa/src/Makefile +++ b/arch/xtensa/src/Makefile @@ -145,11 +145,14 @@ $(AOBJS) $(UAOBJS) $(HEAD_AOBJ): %$(OBJEXT): %.S $(COBJS) $(UCOBJS) $(HEAD_COBJ): %$(OBJEXT): %.c $(call COMPILE, $<, $@) +$(STARTUP_ELF_OBJS): %$(OBJEXT): %.c + $(Q) $(CC) $(CELFFLAGS) -c common$(DELIM)crt0.c -o crt0$(OBJEXT) + ifeq ($(CONFIG_BUILD_FLAT),y) -$(BIN): $(OBJS) +$(BIN): $(STARTUP_ELF_OBJS) $(OBJS) $(call ARCHIVE, $@, $(OBJS)) else -$(BIN): $(UOBJS) +$(BIN): $(STARTUP_ELF_OBJS) $(UOBJS) $(call ARCHIVE, $@, $(UOBJS)) endif diff --git a/arch/xtensa/src/common/Make.defs b/arch/xtensa/src/common/Make.defs index 33c999e0a695b..3d5a58bcacad0 100644 --- a/arch/xtensa/src/common/Make.defs +++ b/arch/xtensa/src/common/Make.defs @@ -22,6 +22,8 @@ # The start-up, "head", file. May be either a .S or a .c file. +STARTUP_ELF_OBJS = crt0$(OBJEXT) + HEAD_ASRC = xtensa_vectors.S xtensa_window_vector.S xtensa_windowspill.S HEAD_ASRC += xtensa_int_handlers.S xtensa_user_handler.S diff --git a/arch/xtensa/src/common/crt0.c b/arch/xtensa/src/common/crt0.c new file mode 100644 index 0000000000000..5732057776abe --- /dev/null +++ b/arch/xtensa/src/common/crt0.c @@ -0,0 +1,153 @@ +/**************************************************************************** + * arch/xtensa/src/common/crt0.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* Linker defined symbols to .ctors and .dtors */ + +extern initializer_t _sctors[]; +extern initializer_t _ectors[]; +extern initializer_t _sdtors[]; +extern initializer_t _edtors[]; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +int main(int argc, char *argv[]); + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +#ifdef CONFIG_HAVE_CXXINITIALIZE + +/**************************************************************************** + * Name: exec_ctors + * + * Description: + * Call static constructors + * + ****************************************************************************/ + +static void exec_ctors(void) +{ + for (initializer_t *ctor = _sctors; ctor != _ectors; ctor++) + { + (*ctor)(); + } +} + +/**************************************************************************** + * Name: exec_dtors + * + * Description: + * Call static destructors + * + ****************************************************************************/ + +static void exec_dtors(void) +{ + for (initializer_t *dtor = _sdtors; dtor != _edtors; dtor++) + { + (*dtor)(); + } +} + +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: __start + * + * Description: + * This function is the low level entry point into the main thread of + * execution of a task. It receives initial control when the task is + * started and calls main entry point of the newly started task. + * + * Input Parameters: + * argc - The number of parameters being passed. + * argv - The parameters being passed. These lie in kernel-space memory + * and will have to be reallocated in user-space memory. + * + * Returned Value: + * This function should not return. It should call the user-mode start-up + * main() function. If that function returns, this function will call + * exit. + * + ****************************************************************************/ + +void __start(int argc, char *argv[]) +{ + int ret; + + /* Initialize the reserved area at the beginning of the .bss/.data region + * that is visible to the RTOS. + */ + +#ifdef CONFIG_BUILD_KERNEL + ARCH_DATA_RESERVE->ar_sigtramp = (addrenv_sigtramp_t)sig_trampoline; +#endif + +#ifdef CONFIG_HAVE_CXXINITIALIZE + /* Call C++ constructors */ + + exec_ctors(); + + /* Setup so that C++ destructors called on task exit */ + +# if CONFIG_LIBC_MAX_EXITFUNS > 0 + atexit(exec_dtors); +# endif +#endif + + /* Call the main() entry point passing argc and argv. */ + + ret = main(argc, argv); + +#if defined(CONFIG_HAVE_CXXINITIALIZE) && CONFIG_LIBC_MAX_EXITFUNS <= 0 + exec_dtors(); +#endif + + /* Call exit() if/when the main() returns */ + + exit(ret); +} diff --git a/arch/xtensa/src/lx6/Toolchain.defs b/arch/xtensa/src/lx6/Toolchain.defs index 7caa075e00f55..5649523ced669 100644 --- a/arch/xtensa/src/lx6/Toolchain.defs +++ b/arch/xtensa/src/lx6/Toolchain.defs @@ -219,3 +219,9 @@ CXXELFFLAGS = $(CXXFLAGS) -fvisibility=hidden -mtext-section-literals LDELFFLAGS = -r -e __start LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)elf$(DELIM)gnu-elf.ld) +ifneq ($(CONFIG_BUILD_KERNEL),y) + # Flat build and protected elf entry point use crt0, + # Kernel build will use apps/import/scripts/crt0 + + LDELFFLAGS += $(TOPDIR)$(DELIM)arch$(DELIM)xtensa$(DELIM)src$(DELIM)crt0.o +endif diff --git a/arch/xtensa/src/lx7/Toolchain.defs b/arch/xtensa/src/lx7/Toolchain.defs index 4aa7a68df003e..9d45f1d9e02a3 100644 --- a/arch/xtensa/src/lx7/Toolchain.defs +++ b/arch/xtensa/src/lx7/Toolchain.defs @@ -223,3 +223,9 @@ CXXELFFLAGS = $(CXXFLAGS) -fvisibility=hidden -mtext-section-literals LDELFFLAGS = -r -e __start LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)elf$(DELIM)gnu-elf.ld) +ifneq ($(CONFIG_BUILD_KERNEL),y) + # Flat build and protected elf entry point use crt0, + # Kernel build will use apps/import/scripts/crt0 + + LDELFFLAGS += $(TOPDIR)$(DELIM)arch$(DELIM)xtensa$(DELIM)src$(DELIM)crt0.o +endif