mirror of
https://github.com/espressif/esp-idf
synced 2025-03-12 10:39:11 -04:00
Merge branch 'bugfix/ext_ram_bss_align_v3.2' into 'release/v3.2'
Fix ext_ram_bss alignment crash (backport v3.2) See merge request idf/esp-idf!4014
This commit is contained in:
commit
52a70e0489
@ -12,6 +12,7 @@ SECTIONS
|
||||
*libpp.a:(.dynsbss .sbss .sbss.* .gnu.linkonce.sb.* .scommon .sbss2.* .gnu.linkonce.sb2.* .dynbss .bss .bss.* .share.mem .gnu.linkonce.b.* COMMON)
|
||||
*liblwip.a:(.dynsbss .sbss .sbss.* .gnu.linkonce.sb.* .scommon .sbss2.* .gnu.linkonce.sb2.* .dynbss .bss .bss.* .share.mem .gnu.linkonce.b.* COMMON)
|
||||
*libbt.a:(EXCLUDE_FILE (libbtdm_app.a) .dynsbss .sbss .sbss.* .gnu.linkonce.sb.* .scommon .sbss2.* .gnu.linkonce.sb2.* .dynbss .bss .bss.* .share.mem .gnu.linkonce.b.* COMMON)
|
||||
. = ALIGN(4);
|
||||
_ext_ram_bss_end = ABSOLUTE(.);
|
||||
} > extern_ram_seg
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ static const char* TAG = "spiram";
|
||||
#endif
|
||||
|
||||
#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
|
||||
extern int _ext_ram_bss_start, _ext_ram_bss_end;
|
||||
extern uint8_t _ext_ram_bss_start, _ext_ram_bss_end;
|
||||
#endif
|
||||
static bool spiram_inited=false;
|
||||
|
||||
|
@ -326,18 +326,21 @@ size_t multi_heap_get_allocated_size_impl(multi_heap_handle_t heap, void *p)
|
||||
return block_data_size(pb);
|
||||
}
|
||||
|
||||
multi_heap_handle_t multi_heap_register_impl(void *start, size_t size)
|
||||
multi_heap_handle_t multi_heap_register_impl(void *start_ptr, size_t size)
|
||||
{
|
||||
heap_t *heap = (heap_t *)ALIGN_UP((intptr_t)start);
|
||||
uintptr_t end = ALIGN((uintptr_t)start + size);
|
||||
if (end - (uintptr_t)start < sizeof(heap_t) + 2*sizeof(heap_block_t)) {
|
||||
uintptr_t start = ALIGN_UP((uintptr_t)start_ptr);
|
||||
uintptr_t end = ALIGN((uintptr_t)start_ptr + size);
|
||||
heap_t *heap = (heap_t *)start;
|
||||
size = end - start;
|
||||
|
||||
if (end < start || size < sizeof(heap_t) + 2*sizeof(heap_block_t)) {
|
||||
return NULL; /* 'size' is too small to fit a heap here */
|
||||
}
|
||||
heap->lock = NULL;
|
||||
heap->last_block = (heap_block_t *)(end - sizeof(heap_block_t));
|
||||
|
||||
/* first 'real' (allocatable) free block goes after the heap structure */
|
||||
heap_block_t *first_free_block = (heap_block_t *)((intptr_t)start + sizeof(heap_t));
|
||||
heap_block_t *first_free_block = (heap_block_t *)(start + sizeof(heap_t));
|
||||
first_free_block->header = (intptr_t)heap->last_block | BLOCK_FREE_FLAG;
|
||||
first_free_block->next_free = heap->last_block;
|
||||
|
||||
@ -356,7 +359,7 @@ multi_heap_handle_t multi_heap_register_impl(void *start, size_t size)
|
||||
- minus header of first_free_block
|
||||
- minus whole block at heap->last_block
|
||||
*/
|
||||
heap->free_bytes = ALIGN(size) - sizeof(heap_t) - sizeof(first_free_block->header) - sizeof(heap_block_t);
|
||||
heap->free_bytes = size - sizeof(heap_t) - sizeof(first_free_block->header) - sizeof(heap_block_t);
|
||||
heap->minimum_free_bytes = heap->free_bytes;
|
||||
|
||||
return heap;
|
||||
|
@ -453,3 +453,44 @@ TEST_CASE("corrupt heap block", "[multi_heap]")
|
||||
memset(a, 0xEE, 64);
|
||||
REQUIRE( !multi_heap_check(heap, true) );
|
||||
}
|
||||
|
||||
TEST_CASE("unaligned heaps", "[multi_heap]")
|
||||
{
|
||||
const size_t CHUNK_LEN = 256;
|
||||
const size_t CANARY_LEN = 16;
|
||||
const uint8_t CANARY_BYTE = 0x3E;
|
||||
uint8_t heap_chunk[CHUNK_LEN + CANARY_LEN * 2];
|
||||
|
||||
/* Put some canary bytes before and after the bytes we intend to use for
|
||||
the heap, make sure they aren't ever overwritten */
|
||||
memset(heap_chunk, CANARY_BYTE, CANARY_LEN);
|
||||
memset(heap_chunk + CANARY_LEN + CHUNK_LEN, CANARY_BYTE, CANARY_LEN);
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
printf("Testing with offset %d\n", i);
|
||||
multi_heap_handle_t heap = multi_heap_register(heap_chunk + CANARY_LEN + i, CHUNK_LEN - i);
|
||||
multi_heap_info_t info;
|
||||
|
||||
REQUIRE( multi_heap_check(heap, true) );
|
||||
|
||||
multi_heap_get_info(heap, &info);
|
||||
|
||||
REQUIRE( info.total_free_bytes > CHUNK_LEN - 64 - i );
|
||||
REQUIRE( info.largest_free_block > CHUNK_LEN - 64 - i );
|
||||
|
||||
void *a = multi_heap_malloc(heap, info.largest_free_block);
|
||||
REQUIRE( a != NULL );
|
||||
memset(a, 0xAA, info.largest_free_block);
|
||||
|
||||
REQUIRE( multi_heap_check(heap, true) );
|
||||
|
||||
multi_heap_free(heap, a);
|
||||
|
||||
REQUIRE( multi_heap_check(heap, true) );
|
||||
|
||||
for (unsigned j = 0; j < CANARY_LEN; j++) { // check canaries
|
||||
REQUIRE( heap_chunk[j] == CANARY_BYTE );
|
||||
REQUIRE( heap_chunk[CHUNK_LEN + CANARY_LEN + j] == CANARY_BYTE );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user