lib c/cpp: Move .ctor .init_array handling from C++ to kernel

* Move ctors and init_array from the CPP library
  to the kernel library, as this is common for both C
  and C++ and it is the kernel who is running it.
* Rename the hidden kconfig option CPP_STATIC_INIT_GNU
  STATIC_INIT_GNU instead.
* If STATIC_INIT_GNU is not selected verify there is
  constructors left behind.
* Rename common-rom-cpp.ld to common-rom-init.ld
* Rename z_cpp_init_static to z_init_static,
  and have the kernel always call it.

Signed-off-by: Alberto Escolar Piedras <alberto.escolar.piedras@nordicsemi.no>
Signed-off-by: Keith Packard <keithp@keithp.com>
This commit is contained in:
Alberto Escolar Piedras 2024-06-21 13:18:55 +02:00 committed by Anas Nashif
parent 5cd580ce44
commit 6e977ae2d5
22 changed files with 149 additions and 131 deletions

View File

@ -142,12 +142,12 @@ SECTIONS {
#include <snippets-rodata.ld>
#include <zephyr/linker/kobject-rom.ld>
#if defined(CONFIG_CPP) && !defined(CONFIG_CPP_STATIC_INIT_GNU) && defined(__MWDT_LINKER_CMD__)
#if defined(CONFIG_CPP) && !defined(CONFIG_STATIC_INIT_GNU) && defined(__MWDT_LINKER_CMD__)
. = ALIGN(4);
_fctors = .;
KEEP(*(.ctors*))
_ectors = .;
#endif /* CONFIG_CPP && !CONFIG_CPP_STATIC_INIT_GNU && __MWDT_LINKER_CMD__ */
#endif /* CONFIG_CPP && !CONFIG_STATIC_INIT_GNU && __MWDT_LINKER_CMD__ */
/* This extra MPU alignment of RAMABLE_REGION is only required if we put ROMABLE_REGION and
* RAMABLE_REGION into the same (continuous) memory - otherwise we can get beginning of the
@ -311,11 +311,11 @@ SECTIONS {
#endif
/DISCARD/ : {
#if defined(CONFIG_CPP) && !defined(CONFIG_CPP_STATIC_INIT_GNU) && defined(__MWDT_LINKER_CMD__)
#if defined(CONFIG_CPP) && !defined(CONFIG_STATIC_INIT_GNU) && defined(__MWDT_LINKER_CMD__)
*(.dtors*)
*(.fini*)
*(.eh_frame*)
#endif /* CONFIG_CPP && !CONFIG_CPP_STATIC_INIT_GNU && __MWDT_LINKER_CMD__ */
#endif /* CONFIG_CPP && !CONFIG_STATIC_INIT_GNU && __MWDT_LINKER_CMD__ */
*(.note.GNU-stack)
*(.got.plt)
*(.igot.plt)

View File

@ -4,7 +4,7 @@
#include <zephyr/linker/common-rom/common-rom-ztest.ld>
#include <zephyr/linker/common-rom/common-rom-cpp.ld>
#include <zephyr/linker/common-rom/common-rom-init.ld>
#include <zephyr/linker/common-rom/common-rom-net.ld>

View File

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: Apache-2.0 */
#ifdef CONFIG_CPP_STATIC_INIT_GNU
#ifdef CONFIG_STATIC_INIT_GNU
SECTION_PROLOGUE(_CTOR_SECTION_NAME,,)
{
/*
@ -59,4 +59,18 @@
KEEP(*(SORT_BY_NAME(".init_array*")))
__zephyr_init_array_end = .;
} GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
#elif defined(CONFIG_TOOLCHAIN_SUPPORTS_STATIC_INIT_GNU)
/*
* If the code to invoke constructors is not enabled,
* make sure there aren't any in the application
*/
SECTION_PROLOGUE(init_array,,)
{
KEEP(*(SORT_BY_NAME(".ctors*")))
KEEP(*(SORT_BY_NAME(".init_array*")))
} GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
ASSERT (SIZEOF(init_array) == 0,
"GNU-style constructors required but STATIC_INIT_GNU not enabled")
#endif

View File

@ -55,6 +55,7 @@ list(APPEND kernel_files
errno.c
fatal.c
init.c
init_static.c
kheap.c
mem_slab.c
float.c

View File

@ -983,6 +983,29 @@ config KERNEL_WHOLE_ARCHIVE
This option forces every object file in the libkernel.a archive
to be included, rather than searching the archive for required object files.
config TOOLCHAIN_SUPPORTS_STATIC_INIT_GNU
# As of today only ARC MWDT toolchain doesn't support GNU-compatible
# initialization of static objects, new toolchains can be added
# here if required.
def_bool "$(ZEPHYR_TOOLCHAIN_VARIANT)" != "arcmwdt"
config STATIC_INIT_GNU
bool "Support GNU-compatible initializers and constructors"
default y if CPP || NATIVE_BUILD || COVERAGE
depends on TOOLCHAIN_SUPPORTS_STATIC_INIT_GNU
depends on !CMAKE_LINKER_GENERATOR
help
GNU-compatible initialization of static objects. This is required for
C++ constructor support as well as for initializer functions as
defined by GNU-compatible toolchains. This increases the size
of Zephyr binaries by around 100 bytes. If you know your
application doesn't need any initializers, you can disable this
option.
The ARC MWDT toolchain, does not support or use this setting,
and has instead separate C++ constructor initialization code.
Note the option CMAKE_LINKER_GENERATOR does not yet support this feature
or CPP.
endmenu
rsource "Kconfig.device"

View File

@ -433,10 +433,8 @@ static void bg_thread_main(void *unused1, void *unused2, void *unused3)
#endif /* CONFIG_STACK_POINTER_RANDOM */
boot_banner();
#if defined(CONFIG_CPP)
void z_cpp_init_static(void);
z_cpp_init_static();
#endif /* CONFIG_CPP */
void z_init_static(void);
z_init_static();
/* Final init level before app starts */
z_sys_init_run_level(INIT_LEVEL_APPLICATION);

87
kernel/init_static.c Normal file
View File

@ -0,0 +1,87 @@
/*
* Copyright (c) 2012-2015 Wind River Systems, Inc.
* Copyright (c) 2021 Synopsys, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
void __do_global_ctors_aux(void);
void __do_init_array_aux(void);
void z_init_static(void)
{
#if defined(CONFIG_STATIC_INIT_GNU)
__do_global_ctors_aux();
__do_init_array_aux();
#elif defined(__CCAC__) /* ARC MWDT */
__do_global_ctors_aux();
#endif
}
/**
* @section - Constructor module
* @brief
* The ctors section contains a list of function pointers that execute both the C++ constructors of
* static global objects, as well as either C or C++ initializer functions (declared with the
* attribute constructor). These must be executed before the application's main() routine.
*
* NOTE: Not all compilers put those function pointers into the ctors section;
* some put them into the init_array section instead.
*/
#ifdef CONFIG_STATIC_INIT_GNU
/* What a constructor function pointer looks like */
typedef void (*CtorFuncPtr)(void);
/* Constructor function pointer list is generated by the linker script. */
extern CtorFuncPtr __ZEPHYR_CTOR_LIST__[];
extern CtorFuncPtr __ZEPHYR_CTOR_END__[];
/**
*
* @brief Invoke all C++ style global object constructors
*
* This routine is invoked by the kernel prior to the execution of the
* application's main().
*/
void __do_global_ctors_aux(void)
{
unsigned int nCtors;
nCtors = (unsigned long)__ZEPHYR_CTOR_LIST__[0];
while (nCtors >= 1U) {
__ZEPHYR_CTOR_LIST__[nCtors--]();
}
}
#endif
/*
* @section
* @brief Execute initialization routines referenced in .init_array section
*/
#ifdef CONFIG_STATIC_INIT_GNU
typedef void (*func_ptr)(void);
extern func_ptr __zephyr_init_array_start[];
extern func_ptr __zephyr_init_array_end[];
/**
* @brief Execute initialization routines referenced in .init_array section
*/
void __do_init_array_aux(void)
{
for (func_ptr *func = __zephyr_init_array_start;
func < __zephyr_init_array_end;
func++) {
(*func)();
}
}
#endif

View File

@ -144,12 +144,12 @@ config CPP_RTTI
endif # !MINIMAL_LIBCPP
config CPP_STATIC_INIT_GNU
# As of today only ARC MWDT toolchain doesn't support GNU-compatible
# initialization of CPP static objects, new toolchains can be added
# here if required.
def_bool "$(ZEPHYR_TOOLCHAIN_VARIANT)" != "arcmwdt"
bool
select STATIC_INIT_GNU
select DEPRECATED
help
GNU-compatible initialization of CPP static objects
GNU-compatible initialization of CPP static objects.
This option is deprecated in favour of STATIC_INIT_GNU
endif # CPP

View File

@ -1,9 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
zephyr_sources(cpp_init.c)
zephyr_sources_ifdef(CONFIG_CPP_STATIC_INIT_GNU
cpp_init_array.c
cpp_ctors.c
zephyr_sources_ifdef(CONFIG_STATIC_INIT_GNU
cpp_dtors.c
)

View File

@ -1,43 +0,0 @@
/*
* Copyright (c) 2012-2014 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file - Constructor module
* @brief
* The ctors section contains a list of function pointers that execute the
* C++ constructors of static global objects. These must be executed before
* the application's main() routine.
*
* NOTE: Not all compilers put those function pointers into the ctors section;
* some put them into the init_array section instead.
*/
/* What a constructor function pointer looks like */
typedef void (*CtorFuncPtr)(void);
/* Constructor function pointer list is generated by the linker script. */
extern CtorFuncPtr __ZEPHYR_CTOR_LIST__[];
extern CtorFuncPtr __ZEPHYR_CTOR_END__[];
/**
*
* @brief Invoke all C++ style global object constructors
*
* This routine is invoked by the kernel prior to the execution of the
* application's main().
*/
void __do_global_ctors_aux(void)
{
unsigned int nCtors;
nCtors = (unsigned long)__ZEPHYR_CTOR_LIST__[0];
while (nCtors >= 1U) {
__ZEPHYR_CTOR_LIST__[nCtors--]();
}
}

View File

@ -1,31 +0,0 @@
/*
* Copyright (c) 2021 Synopsys, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
* Author: Evgeniy Paltsev
*/
#ifdef CONFIG_CPP_STATIC_INIT_GNU
void __do_global_ctors_aux(void);
void __do_init_array_aux(void);
void z_cpp_init_static(void)
{
__do_global_ctors_aux();
__do_init_array_aux();
}
#else
#ifdef __CCAC__
void __do_global_ctors_aux(void);
void z_cpp_init_static(void)
{
__do_global_ctors_aux();
}
#endif /* __CCAC__ */
#endif /* CONFIG_CPP_STATIC_INIT_GNU */

View File

@ -1,27 +0,0 @@
/*
* Copyright (c) 2015 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
/*
* @file
* @brief Execute initialization routines referenced in .init_array section
*/
typedef void (*func_ptr)(void);
extern func_ptr __zephyr_init_array_start[];
extern func_ptr __zephyr_init_array_end[];
/**
* @brief Execute initialization routines referenced in .init_array section
*/
void __do_init_array_aux(void)
{
for (func_ptr *func = __zephyr_init_array_start;
func < __zephyr_init_array_end;
func++) {
(*func)();
}
}

View File

@ -805,7 +805,7 @@ SECTIONS
. = ALIGN(4);
} GROUP_DATA_LINK_IN(RODATA_REGION, ROMABLE_REGION)
#include <zephyr/linker/common-rom/common-rom-cpp.ld>
#include <zephyr/linker/common-rom/common-rom-init.ld>
#include <zephyr/linker/common-rom/common-rom-kernel-devices.ld>
#include <zephyr/linker/common-rom/common-rom-ztest.ld>
#include <zephyr/linker/common-rom/common-rom-net.ld>

View File

@ -209,7 +209,7 @@ SECTIONS
. = ALIGN(4);
} GROUP_DATA_LINK_IN(RODATA_REGION, ROMABLE_DATA_REGION)
#include <zephyr/linker/common-rom/common-rom-cpp.ld>
#include <zephyr/linker/common-rom/common-rom-init.ld>
#include <zephyr/linker/common-rom/common-rom-kernel-devices.ld>
#include <zephyr/linker/common-rom/common-rom-ztest.ld>
#include <zephyr/linker/common-rom/common-rom-net.ld>

View File

@ -771,7 +771,7 @@ SECTIONS
} GROUP_DATA_LINK_IN(RODATA_REGION, ROMABLE_REGION)
#include <zephyr/linker/cplusplus-rom.ld>
#include <zephyr/linker/common-rom/common-rom-cpp.ld>
#include <zephyr/linker/common-rom/common-rom-init.ld>
#include <zephyr/linker/common-rom/common-rom-kernel-devices.ld>
#include <zephyr/linker/common-rom/common-rom-ztest.ld>
#include <zephyr/linker/common-rom/common-rom-net.ld>

View File

@ -225,7 +225,7 @@ SECTIONS
. = ALIGN(4);
} > dram_seg
#include <zephyr/linker/common-rom/common-rom-cpp.ld>
#include <zephyr/linker/common-rom/common-rom-init.ld>
#include <zephyr/linker/common-rom/common-rom-kernel-devices.ld>
#include <zephyr/linker/common-rom/common-rom-debug.ld>
#include <zephyr/linker/common-rom/common-rom-misc.ld>

View File

@ -771,7 +771,7 @@ SECTIONS
} GROUP_DATA_LINK_IN(CACHED_REGION, ROMABLE_REGION)
#include <zephyr/linker/cplusplus-rom.ld>
#include <zephyr/linker/common-rom/common-rom-cpp.ld>
#include <zephyr/linker/common-rom/common-rom-init.ld>
#include <zephyr/linker/common-rom/common-rom-kernel-devices.ld>
#include <zephyr/linker/common-rom/common-rom-ztest.ld>
#include <zephyr/linker/common-rom/common-rom-net.ld>

View File

@ -219,7 +219,7 @@ SECTIONS
. = ALIGN(4);
} > dram_seg
#include <zephyr/linker/common-rom/common-rom-cpp.ld>
#include <zephyr/linker/common-rom/common-rom-init.ld>
#include <zephyr/linker/common-rom/common-rom-kernel-devices.ld>
#include <zephyr/linker/common-rom/common-rom-debug.ld>
#include <zephyr/linker/common-rom/common-rom-misc.ld>

View File

@ -908,7 +908,7 @@ SECTIONS
} GROUP_DATA_LINK_IN(RODATA_REGION, ROMABLE_REGION)
#include <zephyr/linker/cplusplus-rom.ld>
#include <zephyr/linker/common-rom/common-rom-cpp.ld>
#include <zephyr/linker/common-rom/common-rom-init.ld>
#include <zephyr/linker/common-rom/common-rom-kernel-devices.ld>
#include <zephyr/linker/common-rom/common-rom-ztest.ld>
#include <zephyr/linker/common-rom/common-rom-net.ld>

View File

@ -199,7 +199,7 @@ SECTIONS
. = ALIGN(4);
} > dram_seg
#include <zephyr/linker/common-rom/common-rom-cpp.ld>
#include <zephyr/linker/common-rom/common-rom-init.ld>
#include <zephyr/linker/common-rom/common-rom-kernel-devices.ld>
#include <zephyr/linker/common-rom/common-rom-debug.ld>
#include <zephyr/linker/common-rom/common-rom-misc.ld>

View File

@ -843,7 +843,7 @@ SECTIONS
} GROUP_DATA_LINK_IN(RODATA_REGION, ROMABLE_REGION)
#include <zephyr/linker/cplusplus-rom.ld>
#include <zephyr/linker/common-rom/common-rom-cpp.ld>
#include <zephyr/linker/common-rom/common-rom-init.ld>
#include <zephyr/linker/common-rom/common-rom-kernel-devices.ld>
#include <zephyr/linker/common-rom/common-rom-ztest.ld>
#include <zephyr/linker/common-rom/common-rom-net.ld>

View File

@ -185,7 +185,7 @@ SECTIONS
#pragma push_macro("GROUP_ROM_LINK_IN")
#undef GROUP_ROM_LINK_IN
#define GROUP_ROM_LINK_IN(vregion, lregion) > RAMABLE_REGION AT > lregion
#include <zephyr/linker/common-rom/common-rom-cpp.ld>
#include <zephyr/linker/common-rom/common-rom-init.ld>
#include <zephyr/linker/common-rom/common-rom-kernel-devices.ld>
#include <zephyr/linker/common-rom/common-rom-ztest.ld>
#include <zephyr/linker/common-rom/common-rom-net.ld>