mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-01 19:54:32 +02:00
Merge branch 'bugfix/c3_init_priority' into 'master'
fix[cxx/system]: init_priority ordering on RISCV Closes IDF-2206 and IDFGH-4527 See merge request espressif/esp-idf!11660
This commit is contained in:
@@ -180,17 +180,17 @@ struct PriorityInitTest
|
|||||||
int PriorityInitTest::order = 0;
|
int PriorityInitTest::order = 0;
|
||||||
|
|
||||||
// init_priority objects are initialized from the lowest to the heighest priority number
|
// init_priority objects are initialized from the lowest to the heighest priority number
|
||||||
// Default init_priority is always the lowest
|
// Default init_priority is always the lowest (highest priority number)
|
||||||
PriorityInitTest g_static_init_priority_test3;
|
PriorityInitTest g_static_init_priority_test2;
|
||||||
PriorityInitTest g_static_init_priority_test2 __attribute__((init_priority(1000)));
|
PriorityInitTest g_static_init_priority_test1 __attribute__((init_priority(1000)));
|
||||||
PriorityInitTest g_static_init_priority_test1 __attribute__((init_priority(999)));
|
PriorityInitTest g_static_init_priority_test0 __attribute__((init_priority(999)));
|
||||||
|
|
||||||
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C3)
|
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C3)
|
||||||
// TODO ESP32C3 IDF-2206
|
// TODO ESP32C3 IDF-2206
|
||||||
TEST_CASE("init_priority extension works", "[cxx]")
|
TEST_CASE("init_priority extension works", "[cxx]")
|
||||||
{
|
{
|
||||||
TEST_ASSERT_EQUAL(0, g_static_init_priority_test1.index);
|
TEST_ASSERT_EQUAL(0, g_static_init_priority_test0.index);
|
||||||
TEST_ASSERT_EQUAL(1, g_static_init_priority_test2.index);
|
TEST_ASSERT_EQUAL(1, g_static_init_priority_test1.index);
|
||||||
TEST_ASSERT_EQUAL(2, g_static_init_priority_test3.index);
|
TEST_ASSERT_EQUAL(2, g_static_init_priority_test2.index);
|
||||||
}
|
}
|
||||||
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C3)
|
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C3)
|
||||||
|
@@ -304,10 +304,21 @@ SECTIONS
|
|||||||
__eh_frame = ABSOLUTE(.);
|
__eh_frame = ABSOLUTE(.);
|
||||||
KEEP(*(.eh_frame))
|
KEEP(*(.eh_frame))
|
||||||
. = (. + 7) & ~ 3;
|
. = (. + 7) & ~ 3;
|
||||||
/* C++ constructor and destructor tables */
|
/*
|
||||||
/* Don't include anything from crtbegin.o or crtend.o, as IDF doesn't use toolchain crt */
|
* C++ constructor and destructor tables
|
||||||
|
* Don't include anything from crtbegin.o or crtend.o, as IDF doesn't use toolchain crt.
|
||||||
|
*
|
||||||
|
* RISC-V gcc is configured with --enable-initfini-array so it emits an .init_array section instead.
|
||||||
|
* But the init_priority sections will be sorted for iteration in ascending order during startup.
|
||||||
|
* The rest of the init_array sections is sorted for iteration in descending order during startup, however.
|
||||||
|
* Hence a different section is generated for the init_priority functions which is iterated in
|
||||||
|
* ascending order during startup. The corresponding code can be found in startup.c.
|
||||||
|
*/
|
||||||
|
__init_priority_array_start = ABSOLUTE(.);
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array.*))
|
||||||
|
__init_priority_array_end = ABSOLUTE(.);
|
||||||
__init_array_start = ABSOLUTE(.);
|
__init_array_start = ABSOLUTE(.);
|
||||||
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array .ctors .ctors.*))
|
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .init_array))
|
||||||
__init_array_end = ABSOLUTE(.);
|
__init_array_end = ABSOLUTE(.);
|
||||||
KEEP (*crtbegin.*(.dtors))
|
KEEP (*crtbegin.*(.dtors))
|
||||||
KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors))
|
KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors))
|
||||||
|
@@ -134,8 +134,22 @@ static IRAM_ATTR void _Unwind_SetNoFunctionContextInstall_Default(unsigned char
|
|||||||
|
|
||||||
static const char* TAG = "cpu_start";
|
static const char* TAG = "cpu_start";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Xtensa gcc is configured to emit a .ctors section, RISC-V gcc is configured with --enable-initfini-array
|
||||||
|
* so it emits an .init_array section instead.
|
||||||
|
* But the init_priority sections will be sorted for iteration in ascending order during startup.
|
||||||
|
* The rest of the init_array sections is sorted for iteration in descending order during startup, however.
|
||||||
|
* Hence a different section is generated for the init_priority functions which is looped
|
||||||
|
* over in ascending direction instead of descending direction.
|
||||||
|
* The RISC-V-specific behavior is dependent on the linker script esp32c3.project.ld.in.
|
||||||
|
*/
|
||||||
static void do_global_ctors(void)
|
static void do_global_ctors(void)
|
||||||
{
|
{
|
||||||
|
#if __riscv
|
||||||
|
extern void (*__init_priority_array_start)(void);
|
||||||
|
extern void (*__init_priority_array_end)(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
extern void (*__init_array_start)(void);
|
extern void (*__init_array_start)(void);
|
||||||
extern void (*__init_array_end)(void);
|
extern void (*__init_array_end)(void);
|
||||||
|
|
||||||
@@ -149,7 +163,16 @@ static void do_global_ctors(void)
|
|||||||
#endif // CONFIG_COMPILER_CXX_EXCEPTIONS
|
#endif // CONFIG_COMPILER_CXX_EXCEPTIONS
|
||||||
|
|
||||||
void (**p)(void);
|
void (**p)(void);
|
||||||
|
|
||||||
|
#if __riscv
|
||||||
|
for (p = &__init_priority_array_start; p < &__init_priority_array_end; ++p) {
|
||||||
|
ESP_EARLY_LOGD(TAG, "calling init function: %p", *p);
|
||||||
|
(*p)();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
for (p = &__init_array_end - 1; p >= &__init_array_start; --p) {
|
for (p = &__init_array_end - 1; p >= &__init_array_start; --p) {
|
||||||
|
ESP_EARLY_LOGD(TAG, "calling init function: %p", *p);
|
||||||
(*p)();
|
(*p)();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user