Skip to content

Commit d574e07

Browse files
committed
kernel: Unify .ctors and .init_array handling
Handle both of these sections in a single chunk of code instead of separately. We don't need to use the legacy .ctors ABI as both the constructors array and startup logic are managed within a single link result. This can now also be used with ARC MWDT which had been using the .ctors sections but with .init_array semantics. For ARC MWDT, we now always discard .dtors and .fini sections as Zephyr will never cause global destructors to execute. Stop discarding .eh_frame sections so that exception handling works as expected. When building a NATIVE_APPLICATION, we ask the native C library to run all of the constructors to ensure any non-Zephyr constructors are run before main is invoked. It might be "nice" to split the constructors so that the Zephyr constructors were executed by the Zephyr code while the non-Zephyr ones were executed by the native C library. I think that could be done if we knew the pathnames of either the Zephyr or non-Zephyr files. That might make a good future enhancement. Signed-off-by: Keith Packard <[email protected]>
1 parent 5c00d99 commit d574e07

File tree

6 files changed

+73
-169
lines changed

6 files changed

+73
-169
lines changed

include/zephyr/arch/arc/v2/linker.ld

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -142,13 +142,6 @@ SECTIONS {
142142
#include <snippets-rodata.ld>
143143
#include <zephyr/linker/kobject-rom.ld>
144144

145-
#if defined(CONFIG_CPP) && !defined(CONFIG_STATIC_INIT_GNU) && defined(__MWDT_LINKER_CMD__)
146-
. = ALIGN(4);
147-
_fctors = .;
148-
KEEP(*(.ctors*))
149-
_ectors = .;
150-
#endif /* CONFIG_CPP && !CONFIG_STATIC_INIT_GNU && __MWDT_LINKER_CMD__ */
151-
152145
/* This extra MPU alignment of RAMABLE_REGION is only required if we put ROMABLE_REGION and
153146
* RAMABLE_REGION into the same (continuous) memory - otherwise we can get beginning of the
154147
* RAMABLE_REGION in the end of ROMABLE_REGION MPU aperture.
@@ -311,11 +304,9 @@ SECTIONS {
311304
#endif
312305

313306
/DISCARD/ : {
314-
#if defined(CONFIG_CPP) && !defined(CONFIG_STATIC_INIT_GNU) && defined(__MWDT_LINKER_CMD__)
307+
/* Discard all destructors */
315308
*(.dtors*)
316309
*(.fini*)
317-
*(.eh_frame*)
318-
#endif /* CONFIG_CPP && !CONFIG_STATIC_INIT_GNU && __MWDT_LINKER_CMD__ */
319310
*(.note.GNU-stack)
320311
*(.got.plt)
321312
*(.igot.plt)
Lines changed: 44 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,76 +1,63 @@
11
/* SPDX-License-Identifier: Apache-2.0 */
22

3-
#ifdef CONFIG_STATIC_INIT_GNU
4-
SECTION_PROLOGUE(_CTOR_SECTION_NAME,,)
3+
#if defined(CONFIG_TOOLCHAIN_SUPPORTS_STATIC_INIT_GNU) || defined(CONFIG_NATIVE_APPLICATION)
4+
SECTION_PROLOGUE(init_array,,)
55
{
66
/*
7-
* The compiler fills the constructor pointers table below,
8-
* hence symbol __CTOR_LIST__ must be aligned on word
9-
* boundary. To align with the C++ standard, the first element
10-
* of the array contains the number of actual constructors. The
11-
* last element is NULL.
12-
*
13-
* The __CTOR_LIST__ and __CTOR_END__ symbols are always defined
14-
* to result in an empty list. This is necessary to fix an issue
15-
* where the glibc process initialization code on native_posix
16-
* platforms calls constructors before Zephyr loads (issue #39347).
17-
*
18-
* Zephyr's start-up code uses the __ZEPHYR_CTOR_LIST__ and
19-
* __ZEHPYR_CTOR_END__ symbols, so these need to be correctly set.
7+
* Add all of the GNU-style constructors in priority order. Note
8+
* that this doesn't build the ctors in the "usual" fashion with
9+
* a length value first and NULL terminator, but we're creating
10+
* an init_array style list and leaving the ctors list empty
11+
*/
12+
#ifdef CONFIG_NATIVE_APPLICATION
13+
/* Use the native LIBC constructor code so that any native
14+
* constructors get run before main is invoked
15+
*/
16+
__init_array_start = .;
17+
#else
18+
__zephyr_init_array_start = .;
19+
#endif
20+
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*)
21+
SORT_BY_INIT_PRIORITY(.ctors.*)))
22+
KEEP (*(.init_array .ctors))
23+
#ifdef CONFIG_NATIVE_APPLICATION
24+
__init_array_end = .;
25+
#else
26+
__zephyr_init_array_end = .;
27+
#endif
28+
29+
#ifdef CONFIG_NATIVE_LIBC
30+
/*
31+
* The __CTOR_LIST__ and __CTOR_END__ symbols are always defined
32+
* to result in an empty list. This is necessary to fix an issue
33+
* where the glibc process initialization code on native_posix
34+
* platforms calls constructors before Zephyr loads (issue #39347).
2035
*/
21-
#ifdef CONFIG_64BIT
22-
. = ALIGN(8);
23-
__ZEPHYR_CTOR_LIST__ = .;
24-
QUAD((__ZEPHYR_CTOR_END__ - __ZEPHYR_CTOR_LIST__) / 8 - 2)
25-
KEEP(*(SORT_BY_NAME(".ctors*")))
2636
__CTOR_LIST__ = .;
37+
#ifdef CONFIG_64BIT
2738
QUAD(0)
28-
__ZEPHYR_CTOR_END__ = .;
2939
QUAD(0)
30-
__CTOR_END__ = .;
3140
#else
32-
. = ALIGN(4);
33-
__ZEPHYR_CTOR_LIST__ = .;
34-
LONG((__ZEPHYR_CTOR_END__ - __ZEPHYR_CTOR_LIST__) / 4 - 2)
35-
KEEP(*(SORT_BY_NAME(".ctors*")))
36-
__CTOR_LIST__ = .;
3741
LONG(0)
38-
__ZEPHYR_CTOR_END__ = .;
3942
LONG(0)
40-
__CTOR_END__ = .;
4143
#endif
42-
} GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
43-
44-
SECTION_PROLOGUE(init_array,,)
45-
{
44+
__CTOR_END__ = .;
45+
#ifndef CONFIG_NATIVE_APPLICATION
4646
/*
47-
* Similar to the schenanigans required for the __CTOR_LIST__ and
48-
* __CTOR_END__ symbols we define __init_array_start and __init_array_end
49-
* to the same address to define an empty list. This prevents the glibc
50-
* startup code from calling any global constructors before Zephyr loads.
51-
*
52-
* Zephyr's start-up code uses the __zephyr_init_array_start and
53-
* __zephyr_init_array_end sybmols, so these need to be set correctly.
54-
*/
55-
. = ALIGN(4);
47+
* Similar to the schenanigans required for the __CTOR_LIST__ and
48+
* __CTOR_END__ symbols we define __init_array_start and __init_array_end
49+
* to the same address to define an empty list. This prevents the glibc
50+
* startup code from calling any global constructors before Zephyr loads.
51+
*/
5652
__init_array_start = .;
5753
__init_array_end = .;
58-
__zephyr_init_array_start = .;
59-
KEEP(*(SORT_BY_NAME(".init_array*")))
60-
__zephyr_init_array_end = .;
54+
#endif
55+
#endif
6156
} GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
6257

63-
#elif defined(CONFIG_TOOLCHAIN_SUPPORTS_STATIC_INIT_GNU) && !defined(CONFIG_NATIVE_APPLICATION)
64-
/*
65-
* If the code to invoke constructors is not enabled,
66-
* make sure there aren't any in the application
67-
*/
68-
SECTION_PROLOGUE(init_array,,)
69-
{
70-
KEEP(*(SORT_BY_NAME(".ctors*")))
71-
KEEP(*(SORT_BY_NAME(".init_array*")))
72-
} GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
58+
#if !defined(CONFIG_STATIC_INIT_GNU) && !defined(CONFIG_NATIVE_APPLICATION)
59+
ASSERT(__zephyr_init_array_start == __zephyr_init_array_end,
60+
"GNU-style constructors required but STATIC_INIT_GNU not enabled")
61+
#endif
7362

74-
ASSERT (SIZEOF(init_array) == 0,
75-
"GNU-style constructors required but STATIC_INIT_GNU not enabled")
7663
#endif

kernel/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ list(APPEND kernel_files
5555
errno.c
5656
fatal.c
5757
init.c
58-
init_static.c
5958
kheap.c
6059
mem_slab.c
6160
float.c

kernel/Kconfig

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -977,10 +977,10 @@ config KERNEL_WHOLE_ARCHIVE
977977
to be included, rather than searching the archive for required object files.
978978

979979
config TOOLCHAIN_SUPPORTS_STATIC_INIT_GNU
980-
# As of today only ARC MWDT toolchain doesn't support GNU-compatible
981-
# initialization of static objects, new toolchains can be added
982-
# here if required.
983-
def_bool "$(ZEPHYR_TOOLCHAIN_VARIANT)" != "arcmwdt"
980+
# As of today, we don't know of any toolchains that don't create
981+
# either .ctors or .init_array sections containing initializer
982+
# addresses in a fashion compatible with how Zephyr uses them.
983+
def_bool y
984984

985985
config STATIC_INIT_GNU
986986
bool "Support GNU-compatible initializers and constructors"
@@ -990,14 +990,11 @@ config STATIC_INIT_GNU
990990
help
991991
GNU-compatible initialization of static objects. This is required for
992992
C++ constructor support as well as for initializer functions as
993-
defined by GNU-compatible toolchains. This increases the size
994-
of Zephyr binaries by around 100 bytes. If you know your
995-
application doesn't need any initializers, you can disable this
996-
option.
997-
The ARC MWDT toolchain, does not support or use this setting,
998-
and has instead separate C++ constructor initialization code.
999-
Note the option CMAKE_LINKER_GENERATOR does not yet support this feature
1000-
or CPP.
993+
defined by GNU-compatible toolchains. This increases the size of
994+
Zephyr binaries by around 24 bytes. If you know your application
995+
doesn't need any initializers, you can disable this option. The linker
996+
will emit an error if constructors are needed and this option has been
997+
disabled.
1001998

1002999
config BOOTARGS
10031000
bool "Support bootargs"

kernel/init.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,22 @@ static char **prepare_main_args(int *argc)
488488
(*argc)++;
489489
}
490490
}
491+
492+
#endif
493+
494+
#ifdef CONFIG_STATIC_INIT_GNU
495+
496+
extern void (*__zephyr_init_array_start[])();
497+
extern void (*__zephyr_init_array_end[])();
498+
499+
static void z_static_init_gnu(void)
500+
{
501+
void (**fn)();
502+
503+
for (fn = __zephyr_init_array_start; fn != __zephyr_init_array_end; fn++)
504+
(**fn)();
505+
}
506+
491507
#endif
492508

493509
/**
@@ -529,8 +545,9 @@ static void bg_thread_main(void *unused1, void *unused2, void *unused3)
529545
#endif /* CONFIG_STACK_POINTER_RANDOM */
530546
boot_banner();
531547

532-
void z_init_static(void);
533-
z_init_static();
548+
#ifdef CONFIG_STATIC_INIT_GNU
549+
z_static_init_gnu();
550+
#endif /* CONFIG_STATIC_INIT_GNU */
534551

535552
/* Final init level before app starts */
536553
z_sys_init_run_level(INIT_LEVEL_APPLICATION);

kernel/init_static.c

Lines changed: 0 additions & 87 deletions
This file was deleted.

0 commit comments

Comments
 (0)