From 21bd94f1165add75f44583cf51025559d68ab6f5 Mon Sep 17 00:00:00 2001 From: Armando Date: Thu, 12 Sep 2024 09:52:52 +0800 Subject: [PATCH] fix(linker): fixed extern linker symbol type from int to char --- components/esp_psram/mmu_psram_flash.c | 16 ++++++++++++---- components/esp_psram/mmu_psram_flash_v2.c | 16 ++++++++++++---- components/esp_system/port/cpu_start.c | 17 +++++++++++++---- components/spi_flash/flash_mmap.c | 8 ++++---- 4 files changed, 41 insertions(+), 16 deletions(-) diff --git a/components/esp_psram/mmu_psram_flash.c b/components/esp_psram/mmu_psram_flash.c index 64baaaa36c..bb9288410a 100644 --- a/components/esp_psram/mmu_psram_flash.c +++ b/components/esp_psram/mmu_psram_flash.c @@ -136,10 +136,18 @@ esp_err_t mmu_config_psram_rodata_segment(uint32_t start_page, uint32_t psram_si /*---------------------------------------------------------------------------- Part 2 APIs (See @Backgrounds on top of this file) -------------------------------------------------------------------------------*/ -extern int _instruction_reserved_start; -extern int _instruction_reserved_end; -extern int _rodata_reserved_start; -extern int _rodata_reserved_end; +/** + * If using `int`, then for CLANG, with enabled optimization when inlined function is provided with the address of external symbol, the two least bits of the constant used inside that function get cleared. + * Optimizer assumes that address of external symbol should be aligned to 4-bytes and therefore aligns constant value used for bitwise AND operation with that address. + * + * This means `extern int _instruction_reserved_start;` can be unaligned to 4 bytes, whereas using `char` can solve this issue. + * + * As we only use these symbol address, we declare them as `char` here + */ +extern char _instruction_reserved_start; +extern char _instruction_reserved_end; +extern char _rodata_reserved_start; +extern char _rodata_reserved_end; //------------------------------------Copy Flash .text to PSRAM-------------------------------------// #if CONFIG_SPIRAM_FETCH_INSTRUCTIONS diff --git a/components/esp_psram/mmu_psram_flash_v2.c b/components/esp_psram/mmu_psram_flash_v2.c index d29a873bb2..fe9a8407b2 100644 --- a/components/esp_psram/mmu_psram_flash_v2.c +++ b/components/esp_psram/mmu_psram_flash_v2.c @@ -28,10 +28,18 @@ #define ALIGN_UP_BY(num, align) (((num) + ((align) - 1)) & ~((align) - 1)) #define ALIGN_DOWN_BY(num, align) ((num) & (~((align) - 1))) -extern int _instruction_reserved_start; -extern int _instruction_reserved_end; -extern int _rodata_reserved_start; -extern int _rodata_reserved_end; +/** + * If using `int`, then for CLANG, with enabled optimization when inlined function is provided with the address of external symbol, the two least bits of the constant used inside that function get cleared. + * Optimizer assumes that address of external symbol should be aligned to 4-bytes and therefore aligns constant value used for bitwise AND operation with that address. + * + * This means `extern int _instruction_reserved_start;` can be unaligned to 4 bytes, whereas using `char` can solve this issue. + * + * As we only use these symbol address, we declare them as `char` here + */ +extern char _instruction_reserved_start; +extern char _instruction_reserved_end; +extern char _rodata_reserved_start; +extern char _rodata_reserved_end; const static char *TAG = "mmu_psram"; static uint32_t s_irom_vaddr_start; diff --git a/components/esp_system/port/cpu_start.c b/components/esp_system/port/cpu_start.c index ea24e95de5..9e7947bf90 100644 --- a/components/esp_system/port/cpu_start.c +++ b/components/esp_system/port/cpu_start.c @@ -138,10 +138,19 @@ extern int _rtc_bss_end; extern int _bss_bt_start; extern int _bss_bt_end; #endif // CONFIG_BT_LE_RELEASE_IRAM_SUPPORTED -extern int _instruction_reserved_start; -extern int _instruction_reserved_end; -extern int _rodata_reserved_start; -extern int _rodata_reserved_end; + +/** + * If using `int`, then for CLANG, with enabled optimization when inlined function is provided with the address of external symbol, the two least bits of the constant used inside that function get cleared. + * Optimizer assumes that address of external symbol should be aligned to 4-bytes and therefore aligns constant value used for bitwise AND operation with that address. + * + * This means `extern int _instruction_reserved_start;` can be unaligned to 4 bytes, whereas using `char` can solve this issue. + * + * As we only use these symbol address, we declare them as `char` here + */ +extern char _instruction_reserved_start; +extern char _instruction_reserved_end; +extern char _rodata_reserved_start; +extern char _rodata_reserved_end; extern int _vector_table; #if SOC_INT_CLIC_SUPPORTED diff --git a/components/spi_flash/flash_mmap.c b/components/spi_flash/flash_mmap.c index d82db7f811..007324e8df 100644 --- a/components/spi_flash/flash_mmap.c +++ b/components/spi_flash/flash_mmap.c @@ -36,13 +36,13 @@ #include "spi_flash_mmap.h" #if CONFIG_SPIRAM_FETCH_INSTRUCTIONS -extern int _instruction_reserved_start; -extern int _instruction_reserved_end; +extern char _instruction_reserved_start; +extern char _instruction_reserved_end; #endif #if CONFIG_SPIRAM_RODATA -extern int _rodata_reserved_start; -extern int _rodata_reserved_end; +extern char _rodata_reserved_start; +extern char _rodata_reserved_end; #endif #if !CONFIG_SPI_FLASH_ROM_IMPL