Skip to content

arch/xtensa: add crt0 to initialize environment #16208

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions arch/xtensa/src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 2 additions & 0 deletions arch/xtensa/src/common/Make.defs
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
153 changes: 153 additions & 0 deletions arch/xtensa/src/common/crt0.c
Original file line number Diff line number Diff line change
@@ -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 <nuttx/config.h>

#include <sys/types.h>
#include <stdlib.h>

#include <nuttx/addrenv.h>
#include <nuttx/arch.h>

#include <arch/syscall.h>

/****************************************************************************
* 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);
}
6 changes: 6 additions & 0 deletions arch/xtensa/src/lx6/Toolchain.defs
Original file line number Diff line number Diff line change
Expand Up @@ -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
6 changes: 6 additions & 0 deletions arch/xtensa/src/lx7/Toolchain.defs
Original file line number Diff line number Diff line change
Expand Up @@ -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