From 497cb2e58795142fb3b117eecf21ca8497b04e0a Mon Sep 17 00:00:00 2001 From: Evgeniy Paltsev Date: Mon, 26 Apr 2021 16:15:49 +0300 Subject: [PATCH] CPP: fix static objects init for MWDT toolchain The constructors of static objects are stored in ".ctors" section. In case of MWDT toolchain we have incompatible ".ctors" section format with GNU toolchain. So let's use initialization code provided by MWDT instead of Zephyr one in case of MWDT toolchain usage. As it is done for GNU toolchain We call constructors of static objects but we don't call destructors for them. Signed-off-by: Eugeniy Paltsev Signed-off-by: Evgeniy Paltsev --- cmake/linker/arcmwdt/target.cmake | 6 +++++- include/arch/arc/v2/linker.ld | 19 +++++++++++++++++++ include/linker/common-rom.ld | 2 +- kernel/init.c | 7 ++----- subsys/cpp/CMakeLists.txt | 4 +++- subsys/cpp/Kconfig | 8 ++++++++ subsys/cpp/cpp_init.c | 31 +++++++++++++++++++++++++++++++ 7 files changed, 69 insertions(+), 8 deletions(-) create mode 100644 subsys/cpp/cpp_init.c diff --git a/cmake/linker/arcmwdt/target.cmake b/cmake/linker/arcmwdt/target.cmake index 1db1f6f307b..b522685fdff 100644 --- a/cmake/linker/arcmwdt/target.cmake +++ b/cmake/linker/arcmwdt/target.cmake @@ -112,7 +112,6 @@ macro(toolchain_ld_baremetal) zephyr_ld_options( -Hlld -Hnosdata - -Hnocrt -Xtimer0 # to suppress the warning message -Hnoxcheck_obj -Hnocplus @@ -120,6 +119,11 @@ macro(toolchain_ld_baremetal) -Hnoivt ) + # We only use CPP initialization code from crt + if(NOT CONFIG_CPLUSPLUS) + zephyr_ld_options(-Hnocrt) + endif() + # Funny thing is if this is set to =error, some architectures will # skip this flag even though the compiler flag check passes # (e.g. ARC and Xtensa). So warning should be the default for now. diff --git a/include/arch/arc/v2/linker.ld b/include/arch/arc/v2/linker.ld index 23a912a3a33..9fef45edcdd 100644 --- a/include/arch/arc/v2/linker.ld +++ b/include/arch/arc/v2/linker.ld @@ -94,6 +94,13 @@ SECTIONS { #include } GROUP_LINK_IN(ROMABLE_REGION) +#if defined(CONFIG_CPLUSPLUS) && !defined(CONFIG_CPP_STATIC_INIT_GNU) && defined(__MWDT_LINKER_CMD__) + /* .init section with code iterating over static objects constructors */ + SECTION_PROLOGUE(.init,,ALIGN(4)) { + KEEP(*(.init*)) + } GROUP_LINK_IN(ROMABLE_REGION) +#endif /* CONFIG_CPLUSPLUS && !CONFIG_CPP_STATIC_INIT_GNU && __MWDT_LINKER_CMD__ */ + _image_text_end = .; _image_rodata_start = .; @@ -111,6 +118,13 @@ SECTIONS { #include #include + +#if defined(CONFIG_CPLUSPLUS) && !defined(CONFIG_CPP_STATIC_INIT_GNU) && defined(__MWDT_LINKER_CMD__) + . = ALIGN(4); + _fctors = .; + KEEP(*(.ctors*)) + _ectors = .; +#endif /* CONFIG_CPLUSPLUS && !CONFIG_CPP_STATIC_INIT_GNU && __MWDT_LINKER_CMD__ */ } GROUP_LINK_IN(ROMABLE_REGION) #ifdef __MWDT_LINKER_CMD__ @@ -225,6 +239,11 @@ SECTIONS { } /DISCARD/ : { +#if defined(CONFIG_CPLUSPLUS) && !defined(CONFIG_CPP_STATIC_INIT_GNU) && defined(__MWDT_LINKER_CMD__) + *(.dtors*) + *(.fini*) + *(.eh_frame*) +#endif /* CONFIG_CPLUSPLUS && !CONFIG_CPP_STATIC_INIT_GNU && __MWDT_LINKER_CMD__ */ *(.note.GNU-stack) *(.got.plt) *(.igot.plt) diff --git a/include/linker/common-rom.ld b/include/linker/common-rom.ld index bbed3126420..453655c349a 100644 --- a/include/linker/common-rom.ld +++ b/include/linker/common-rom.ld @@ -52,7 +52,7 @@ } ASSERT(SIZEOF(initlevel_error) == 0, "Undefined initialization levels used.") -#ifdef CONFIG_CPLUSPLUS +#ifdef CONFIG_CPP_STATIC_INIT_GNU SECTION_PROLOGUE(_CTOR_SECTION_NAME,,) { /* diff --git a/kernel/init.c b/kernel/init.c index 4b587cdc72f..6859c5bbcd4 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -198,11 +198,8 @@ static void bg_thread_main(void *unused1, void *unused2, void *unused3) boot_banner(); #if defined(CONFIG_CPLUSPLUS) && !defined(CONFIG_ARCH_POSIX) - /* Process the .ctors and .init_array sections */ - extern void __do_global_ctors_aux(void); - extern void __do_init_array_aux(void); - __do_global_ctors_aux(); - __do_init_array_aux(); + void z_cpp_init_static(void); + z_cpp_init_static(); #endif /* Final init level before app starts */ diff --git a/subsys/cpp/CMakeLists.txt b/subsys/cpp/CMakeLists.txt index d61a659dcac..9f606e02514 100644 --- a/subsys/cpp/CMakeLists.txt +++ b/subsys/cpp/CMakeLists.txt @@ -1,6 +1,8 @@ # SPDX-License-Identifier: Apache-2.0 -zephyr_sources( +zephyr_sources(cpp_init.c) + +zephyr_sources_ifdef(CONFIG_CPP_STATIC_INIT_GNU cpp_init_array.c cpp_ctors.c cpp_dtors.c diff --git a/subsys/cpp/Kconfig b/subsys/cpp/Kconfig index a4e7bc47a0d..c8738c5678a 100644 --- a/subsys/cpp/Kconfig +++ b/subsys/cpp/Kconfig @@ -75,4 +75,12 @@ config RTTI endif # LIB_CPLUSPLUS +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" + help + GNU-compatible initialization of CPP static objects + endif # CPLUSPLUS diff --git a/subsys/cpp/cpp_init.c b/subsys/cpp/cpp_init.c new file mode 100644 index 00000000000..a3a67719bb5 --- /dev/null +++ b/subsys/cpp/cpp_init.c @@ -0,0 +1,31 @@ +/* + * 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 _init(void); + +void z_cpp_init_static(void) +{ + _init(); +} +#endif /* __CCAC__ */ + +#endif /* CONFIG_CPP_STATIC_INIT_GNU */