From 0f3f44be62dd5036548abc21bead59bd4d4d120a Mon Sep 17 00:00:00 2001 From: Guillaume Souchere Date: Thu, 17 Jul 2025 13:32:28 +0200 Subject: [PATCH] feat(heap): Add hidden Kconfig option to allow exec cap --- components/heap/Kconfig | 5 +++++ components/heap/heap_caps_base.c | 2 +- components/heap/include/esp_heap_caps.h | 2 +- .../heap/test_apps/heap_tests/main/test_diram.c | 4 ++-- .../heap/test_apps/heap_tests/main/test_malloc.c | 2 +- .../test_apps/heap_tests/main/test_malloc_caps.c | 12 ++++++------ tools/idf_py_actions/hints.yml | 2 +- 7 files changed, 17 insertions(+), 12 deletions(-) diff --git a/components/heap/Kconfig b/components/heap/Kconfig index e7cb7adee4..0988bf03dc 100644 --- a/components/heap/Kconfig +++ b/components/heap/Kconfig @@ -1,5 +1,10 @@ menu "Heap memory debugging" + config HEAP_HAS_EXEC_HEAP + bool + default n if ESP_SYSTEM_MEMPROT + default y if !ESP_SYSTEM_MEMPROT + choice HEAP_CORRUPTION_DETECTION prompt "Heap corruption detection" default HEAP_POISONING_DISABLED diff --git a/components/heap/heap_caps_base.c b/components/heap/heap_caps_base.c index f6e8b5bdd1..5118b672c3 100644 --- a/components/heap/heap_caps_base.c +++ b/components/heap/heap_caps_base.c @@ -116,7 +116,7 @@ HEAP_IRAM_ATTR NOINLINE_ATTR void *heap_caps_aligned_alloc_base(size_t alignment return NULL; } -#if !(CONFIG_ESP_SYSTEM_MEMPROT_FEATURE || CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT) +#if CONFIG_HEAP_HAS_EXEC_HEAP const bool exec_in_caps = caps & MALLOC_CAP_EXEC; if (exec_in_caps) { //MALLOC_CAP_EXEC forces an alloc from IRAM. There is a region which has both this as well as the following diff --git a/components/heap/include/esp_heap_caps.h b/components/heap/include/esp_heap_caps.h index 0b73d9a84e..d060ed6a57 100644 --- a/components/heap/include/esp_heap_caps.h +++ b/components/heap/include/esp_heap_caps.h @@ -26,7 +26,7 @@ extern "C" { /** * @brief Flags to indicate the capabilities of the various memory systems */ -#if !(CONFIG_ESP_SYSTEM_MEMPROT_FEATURE || CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT) +#if CONFIG_HEAP_HAS_EXEC_HEAP #define MALLOC_CAP_EXEC (1<<0) ///< Memory must be able to run executable code #endif #define MALLOC_CAP_32BIT (1<<1) ///< Memory must allow for aligned 32-bit data accesses diff --git a/components/heap/test_apps/heap_tests/main/test_diram.c b/components/heap/test_apps/heap_tests/main/test_diram.c index 39a1716f0c..e70db5718e 100644 --- a/components/heap/test_apps/heap_tests/main/test_diram.c +++ b/components/heap/test_apps/heap_tests/main/test_diram.c @@ -15,7 +15,7 @@ #define ALLOC_SZ 1024 -#if !(CONFIG_ESP_SYSTEM_MEMPROT_FEATURE || CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT) +#if CONFIG_HEAP_HAS_EXEC_HEAP static void *malloc_block_diram(uint32_t caps) { void *attempts[256] = { 0 }; // Allocate up to 256 ALLOC_SZ blocks to exhaust all non-D/IRAM memory temporarily @@ -78,4 +78,4 @@ TEST_CASE("Allocate D/IRAM as IRAM", "[heap][qemu-ignore]") free(iram); } -#endif // !(CONFIG_ESP_SYSTEM_MEMPROT_FEATURE || CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT) +#endif // CONFIG_HEAP_HAS_EXEC_HEAP diff --git a/components/heap/test_apps/heap_tests/main/test_malloc.c b/components/heap/test_apps/heap_tests/main/test_malloc.c index 152cd22bdb..cbf7793634 100644 --- a/components/heap/test_apps/heap_tests/main/test_malloc.c +++ b/components/heap/test_apps/heap_tests/main/test_malloc.c @@ -154,7 +154,7 @@ TEST_CASE("alloc overflows should all fail", "[heap]") /* will overflow when the size is rounded up to word align it */ TEST_ASSERT_NULL(heap_caps_malloc(SIZE_MAX-1, MALLOC_CAP_32BIT)); -#if !(CONFIG_ESP_SYSTEM_MEMPROT_FEATURE || CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT) +#if CONFIG_HEAP_HAS_EXEC_HEAP TEST_ASSERT_NULL(heap_caps_malloc(SIZE_MAX-1, MALLOC_CAP_EXEC)); #endif } diff --git a/components/heap/test_apps/heap_tests/main/test_malloc_caps.c b/components/heap/test_apps/heap_tests/main/test_malloc_caps.c index f9e79791e8..08d7cb55ce 100644 --- a/components/heap/test_apps/heap_tests/main/test_malloc_caps.c +++ b/components/heap/test_apps/heap_tests/main/test_malloc_caps.c @@ -18,7 +18,7 @@ #include #include -#if !CONFIG_ESP_SYSTEM_MEMPROT && !CONFIG_HEAP_TASK_TRACKING +#if CONFIG_HEAP_HAS_EXEC_HEAP && !(CONFIG_HEAP_TASK_TRACKING) TEST_CASE("Capabilities allocator test", "[heap]") { char *m1, *m2[10]; @@ -108,7 +108,7 @@ TEST_CASE("Capabilities allocator test", "[heap]") free(m1); printf("Done.\n"); } -#endif // !CONFIG_ESP_SYSTEM_MEMPROT && !CONFIG_HEAP_TASK_TRACKING +#endif // CONFIG_HEAP_HAS_EXEC_HEAP && !(CONFIG_HEAP_TASK_TRACKING) #ifdef CONFIG_ESP32_IRAM_AS_8BIT_ACCESSIBLE_MEMORY TEST_CASE("IRAM_8BIT capability test", "[heap]") @@ -230,7 +230,7 @@ TEST_CASE("heap caps minimum free bytes fault cases", "[heap]") /* Small function runs from IRAM to check that malloc/free/realloc all work OK when cache is disabled... */ -#if !CONFIG_ESP_SYSTEM_MEMPROT && !CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH && !CONFIG_HEAP_TASK_TRACKING +#if CONFIG_HEAP_HAS_EXEC_HEAP && !CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH && !CONFIG_HEAP_TASK_TRACKING static IRAM_ATTR __attribute__((noinline)) bool iram_malloc_test(void) { spi_flash_guard_get()->start(); // Disables flash cache @@ -252,7 +252,7 @@ TEST_CASE("heap_caps_xxx functions work with flash cache disabled", "[heap]") { TEST_ASSERT( iram_malloc_test() ); } -#endif // !CONFIG_ESP_SYSTEM_MEMPROT && !CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH && !CONFIG_HEAP_TASK_TRACKING +#endif // CONFIG_HEAP_HAS_EXEC_HEAP && !CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH && !CONFIG_HEAP_TASK_TRACKING #ifdef CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS TEST_CASE("When enabled, allocation operation failure generates an abort", "[heap][reset=abort,SW_CPU_RESET]") @@ -336,7 +336,7 @@ TEST_CASE("RTC memory should be lowest priority and its free size should be big } #endif -#if !(CONFIG_ESP_SYSTEM_MEMPROT_FEATURE || CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT) +#if CONFIG_HEAP_HAS_EXEC_HEAP TEST_CASE("test memory protection features", "[heap][mem_prot]") { // try to allocate memory in IRAM and check that if memory protection is active, @@ -351,4 +351,4 @@ TEST_CASE("test memory protection features", "[heap][mem_prot]") // free the memory heap_caps_free(iram_ptr); } -#endif // !(CONFIG_ESP_SYSTEM_MEMPROT_FEATURE || CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT) +#endif // CONFIG_HEAP_HAS_EXEC_HEAP diff --git a/tools/idf_py_actions/hints.yml b/tools/idf_py_actions/hints.yml index f9a265c46c..83fc65e85a 100644 --- a/tools/idf_py_actions/hints.yml +++ b/tools/idf_py_actions/hints.yml @@ -700,4 +700,4 @@ - re: "error: 'MALLOC_CAP_EXEC' undeclared \\(first use in this function\\)" - hint: "MALLOC_CAP_EXEC capability cannot be used if CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT or CONFIG_ESP_SYSTEM_MEMPROT_FEATURE is enlabled. \nFor further information about those configurations, run 'idf.py docs -sp api-reference/kconfig-reference.html#memory-protection'" + hint: "MALLOC_CAP_EXEC capability cannot be used if CONFIG_ESP_SYSTEM_PMP_IDRAM_SPLIT or CONFIG_ESP_SYSTEM_MEMPROT_FEATURE is enabled. \nFor further information about those configurations, run 'idf.py docs -sp api-reference/kconfig-reference.html#memory-protection'"