From 31145f38fa3e1649fe357efd03a50e8c4882b0b0 Mon Sep 17 00:00:00 2001 From: Felipe Neves Date: Tue, 19 Nov 2019 15:36:22 -0300 Subject: [PATCH] heap_caps: added special case for realloc when previous area is an diram_iram ptr, this will force a malloc/copy/free --- components/heap/heap_caps.c | 37 ++++++++++++++++++++------ components/heap/multi_heap_poisoning.c | 21 ++------------- 2 files changed, 31 insertions(+), 27 deletions(-) diff --git a/components/heap/heap_caps.c b/components/heap/heap_caps.c index 316612cf6f..2661bcb611 100644 --- a/components/heap/heap_caps.c +++ b/components/heap/heap_caps.c @@ -275,6 +275,10 @@ IRAM_ATTR void heap_caps_free( void *ptr) IRAM_ATTR void *heap_caps_realloc( void *ptr, size_t size, int caps) { + bool ptr_in_diram_case = false; + heap_t *heap = NULL; + void *dram_ptr = NULL; + if (ptr == NULL) { return heap_caps_malloc(size, caps); } @@ -288,23 +292,32 @@ IRAM_ATTR void *heap_caps_realloc( void *ptr, size_t size, int caps) return NULL; } - //On esp32s2 the pointer to heap may be aliased, we need to + //The pointer to memory may be aliased, we need to //recover it before to manage a new allocation: if(esp_ptr_in_diram_iram((void *)ptr)) { - //pointer must be already aliased, otherwise just ignore this part: uint32_t *dram_addr = (uint32_t *)ptr; - ptr = (void *)dram_addr[-1]; + dram_ptr = (void *)dram_addr[-1]; + //printf("[HEAP_CAPS_MALLOC]: obtained pointer that was aliased: %p \n", (void *)ptr); + + heap = find_containing_heap(dram_ptr); + assert(heap != NULL && "realloc() pointer is outside heap areas"); + + //with pointers that reside on diram space, we avoid to + //to use realloc implementation due to address translation issues, + //instead force a malloc/copy/free + ptr_in_diram_case = true; + + } else { + heap = find_containing_heap(ptr); + assert(heap != NULL && "realloc() pointer is outside heap areas"); } - heap_t *heap = find_containing_heap(ptr); - assert(heap != NULL && "realloc() pointer is outside heap areas"); - // are the existing heap's capabilities compatible with the // requested ones? bool compatible_caps = (caps & get_all_caps(heap)) == caps; - if (compatible_caps) { + if (compatible_caps && !ptr_in_diram_case) { // try to reallocate this memory within the same heap // (which will resize the block if it can) void *r = multi_heap_realloc(heap->heap, ptr, size); @@ -317,8 +330,16 @@ IRAM_ATTR void *heap_caps_realloc( void *ptr, size_t size, int caps) // in a different heap with requested capabilities. void *new_p = heap_caps_malloc(size, caps); if (new_p != NULL) { + size_t old_size = 0; + + //If we're dealing with aliased ptr, information regarding its containing + //heap can only be obtained with translated address. + if(ptr_in_diram_case) { + old_size = multi_heap_get_allocated_size(heap->heap, dram_ptr); + } else { + old_size = multi_heap_get_allocated_size(heap->heap, ptr); + } - size_t old_size = multi_heap_get_allocated_size(heap->heap, ptr); assert(old_size > 0); memcpy(new_p, ptr, MIN(size, old_size)); heap_caps_free(ptr); diff --git a/components/heap/multi_heap_poisoning.c b/components/heap/multi_heap_poisoning.c index 3717b6c299..ffe885150d 100644 --- a/components/heap/multi_heap_poisoning.c +++ b/components/heap/multi_heap_poisoning.c @@ -21,10 +21,6 @@ #include #include #include "multi_heap_internal.h" -#if CONFIG_IDF_TARGET_ESP32S2BETA - #include "heap_private.h" -#endif - /* Note: Keep platform-specific parts in this header, this source file should depend on libc only */ @@ -272,21 +268,8 @@ void *multi_heap_realloc(multi_heap_handle_t heap, void *p, size_t size) new_head = multi_heap_malloc_impl(heap, size + POISON_OVERHEAD); if (new_head != NULL) { result = poison_allocated_region(new_head, size); - -#if CONFIG_IDF_TARGET_ESP32S2BETA - //We may need to deal with aliased heap pointers. here too, - //mainly because the heap canary is located before the - //the slot reserved to preserve original DRAM address - //so the original user data is actually p + 4 ahead : - if(esp_ptr_in_diram_dram((void *)p)) { - memcpy(result, p + sizeof(intptr_t), MIN(size, orig_alloc_size)); - } else { - memcpy(result, p , MIN(size, orig_alloc_size)); - } -#else - memcpy(result, p, MIN(size, orig_alloc_size)); -#endif - multi_heap_free(heap, p); + memcpy(result, p, MIN(size, orig_alloc_size)); + multi_heap_free(heap, p); } #endif