mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 03:00:34 +03:00
Merge branch 'fix/heap-integrity-check-rom-tlsf_v6.0' into 'release/v6.0'
fix(esp_rom): Set poison check hook for tlsf_walk_pool patch (v6.0) See merge request espressif/esp-idf!47893
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include "esp_rom_tlsf.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief TLSF ROM vtable stub table for esp32c2.
|
||||
*
|
||||
* This struct mirrors the TLSF function-pointer vtable stored in ROM.
|
||||
* Its layout MUST exactly match the ROM vtable for the target chip.
|
||||
* It is used by tlsf_set_rom_patches() to intercept TLSF calls.
|
||||
*/
|
||||
struct heap_tlsf_stub_table_t {
|
||||
tlsf_t (*tlsf_create)(void* mem);
|
||||
tlsf_t (*tlsf_create_with_pool)(void* mem, size_t bytes);
|
||||
pool_t (*tlsf_get_pool)(tlsf_t tlsf);
|
||||
pool_t (*tlsf_add_pool)(tlsf_t tlsf, void* mem, size_t bytes);
|
||||
void (*tlsf_remove_pool)(tlsf_t tlsf, pool_t pool);
|
||||
|
||||
void* (*tlsf_malloc)(tlsf_t tlsf, size_t size);
|
||||
void* (*tlsf_memalign)(tlsf_t tlsf, size_t align, size_t size);
|
||||
void* (*tlsf_memalign_offs)(tlsf_t tlsf, size_t align, size_t size, size_t offset);
|
||||
void* (*tlsf_realloc)(tlsf_t tlsf, void* ptr, size_t size);
|
||||
void (*tlsf_free)(tlsf_t tlsf, void* ptr);
|
||||
|
||||
size_t (*tlsf_block_size)(void* ptr);
|
||||
size_t (*tlsf_size)(void);
|
||||
size_t (*tlsf_align_size)(void);
|
||||
size_t (*tlsf_block_size_min)(void);
|
||||
size_t (*tlsf_block_size_max)(void);
|
||||
size_t (*tlsf_pool_overhead)(void);
|
||||
size_t (*tlsf_alloc_overhead)(void);
|
||||
|
||||
void (*tlsf_walk_pool)(pool_t pool, tlsf_walker walker, void* user);
|
||||
|
||||
int (*tlsf_check)(tlsf_t tlsf);
|
||||
int (*tlsf_check_pool)(pool_t pool);
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include "esp_rom_tlsf.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief TLSF ROM vtable stub table for esp32c5.
|
||||
*
|
||||
* This struct mirrors the TLSF function-pointer vtable stored in ROM.
|
||||
* Its layout MUST exactly match the ROM vtable for the target chip.
|
||||
* It is used by tlsf_set_rom_patches() to intercept TLSF calls.
|
||||
*/
|
||||
struct heap_tlsf_stub_table_t {
|
||||
tlsf_t (*tlsf_create)(void *mem, size_t max_bytes);
|
||||
tlsf_t (*tlsf_create_with_pool)(void *mem, size_t pool_bytes, size_t max_bytes);
|
||||
pool_t (*tlsf_get_pool)(tlsf_t tlsf);
|
||||
pool_t (*tlsf_add_pool)(tlsf_t tlsf, void *mem, size_t bytes);
|
||||
void (*tlsf_remove_pool)(tlsf_t tlsf, pool_t pool);
|
||||
|
||||
void *(*tlsf_malloc)(tlsf_t tlsf, size_t size);
|
||||
void *(*tlsf_memalign)(tlsf_t tlsf, size_t align, size_t size);
|
||||
void *(*tlsf_memalign_offs)(tlsf_t tlsf, size_t align, size_t size, size_t offset);
|
||||
void *(*tlsf_realloc)(tlsf_t tlsf, void *ptr, size_t size);
|
||||
void (*tlsf_free)(tlsf_t tlsf, void *ptr);
|
||||
|
||||
size_t (*tlsf_block_size)(void *ptr);
|
||||
size_t (*tlsf_size)(tlsf_t tlsf);
|
||||
size_t (*tlsf_align_size)(void);
|
||||
size_t (*tlsf_block_size_min)(void);
|
||||
size_t (*tlsf_block_size_max)(tlsf_t tlsf);
|
||||
size_t (*tlsf_pool_overhead)(void);
|
||||
size_t (*tlsf_alloc_overhead)(void);
|
||||
|
||||
void (*tlsf_walk_pool)(pool_t pool, tlsf_walker walker, void *user);
|
||||
|
||||
int (*tlsf_check)(tlsf_t tlsf);
|
||||
int (*tlsf_check_pool)(pool_t pool);
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include "esp_rom_tlsf.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief TLSF ROM vtable stub table for esp32c6.
|
||||
*
|
||||
* This struct mirrors the TLSF function-pointer vtable stored in ROM.
|
||||
* Its layout MUST exactly match the ROM vtable for the target chip.
|
||||
* It is used by tlsf_set_rom_patches() to intercept TLSF calls.
|
||||
*/
|
||||
struct heap_tlsf_stub_table_t {
|
||||
tlsf_t (*tlsf_create)(void* mem);
|
||||
tlsf_t (*tlsf_create_with_pool)(void* mem, size_t bytes);
|
||||
pool_t (*tlsf_get_pool)(tlsf_t tlsf);
|
||||
pool_t (*tlsf_add_pool)(tlsf_t tlsf, void* mem, size_t bytes);
|
||||
void (*tlsf_remove_pool)(tlsf_t tlsf, pool_t pool);
|
||||
|
||||
void* (*tlsf_malloc)(tlsf_t tlsf, size_t size);
|
||||
void* (*tlsf_memalign)(tlsf_t tlsf, size_t align, size_t size);
|
||||
void* (*tlsf_memalign_offs)(tlsf_t tlsf, size_t align, size_t size, size_t offset);
|
||||
void* (*tlsf_realloc)(tlsf_t tlsf, void* ptr, size_t size);
|
||||
void (*tlsf_free)(tlsf_t tlsf, void* ptr);
|
||||
|
||||
size_t (*tlsf_block_size)(void* ptr);
|
||||
size_t (*tlsf_size)(void);
|
||||
size_t (*tlsf_align_size)(void);
|
||||
size_t (*tlsf_block_size_min)(void);
|
||||
size_t (*tlsf_block_size_max)(void);
|
||||
size_t (*tlsf_pool_overhead)(void);
|
||||
size_t (*tlsf_alloc_overhead)(void);
|
||||
|
||||
void (*tlsf_walk_pool)(pool_t pool, tlsf_walker walker, void* user);
|
||||
|
||||
int (*tlsf_check)(tlsf_t tlsf);
|
||||
int (*tlsf_check_pool)(pool_t pool);
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include "esp_rom_tlsf.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief TLSF ROM vtable stub table for esp32c61.
|
||||
*
|
||||
* This struct mirrors the TLSF function-pointer vtable stored in ROM.
|
||||
* Its layout MUST exactly match the ROM vtable for the target chip.
|
||||
* It is used by tlsf_set_rom_patches() to intercept TLSF calls.
|
||||
*/
|
||||
struct heap_tlsf_stub_table_t {
|
||||
tlsf_t (*tlsf_create)(void *mem, size_t max_bytes);
|
||||
tlsf_t (*tlsf_create_with_pool)(void *mem, size_t pool_bytes, size_t max_bytes);
|
||||
pool_t (*tlsf_get_pool)(tlsf_t tlsf);
|
||||
pool_t (*tlsf_add_pool)(tlsf_t tlsf, void *mem, size_t bytes);
|
||||
void (*tlsf_remove_pool)(tlsf_t tlsf, pool_t pool);
|
||||
|
||||
void *(*tlsf_malloc)(tlsf_t tlsf, size_t size);
|
||||
void *(*tlsf_memalign)(tlsf_t tlsf, size_t align, size_t size);
|
||||
void *(*tlsf_memalign_offs)(tlsf_t tlsf, size_t align, size_t size, size_t offset);
|
||||
void *(*tlsf_realloc)(tlsf_t tlsf, void *ptr, size_t size);
|
||||
void (*tlsf_free)(tlsf_t tlsf, void *ptr);
|
||||
|
||||
size_t (*tlsf_block_size)(void *ptr);
|
||||
size_t (*tlsf_size)(tlsf_t tlsf);
|
||||
size_t (*tlsf_align_size)(void);
|
||||
size_t (*tlsf_block_size_min)(void);
|
||||
size_t (*tlsf_block_size_max)(tlsf_t tlsf);
|
||||
size_t (*tlsf_pool_overhead)(void);
|
||||
size_t (*tlsf_alloc_overhead)(void);
|
||||
|
||||
void (*tlsf_walk_pool)(pool_t pool, tlsf_walker walker, void *user);
|
||||
|
||||
int (*tlsf_check)(tlsf_t tlsf);
|
||||
int (*tlsf_check_pool)(pool_t pool);
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include "esp_rom_tlsf.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief TLSF ROM vtable stub table for esp32h2.
|
||||
*
|
||||
* This struct mirrors the TLSF function-pointer vtable stored in ROM.
|
||||
* Its layout MUST exactly match the ROM vtable for the target chip.
|
||||
* It is used by tlsf_set_rom_patches() to intercept TLSF calls.
|
||||
*/
|
||||
struct heap_tlsf_stub_table_t {
|
||||
tlsf_t (*tlsf_create)(void *mem, size_t max_bytes);
|
||||
tlsf_t (*tlsf_create_with_pool)(void *mem, size_t pool_bytes, size_t max_bytes);
|
||||
pool_t (*tlsf_get_pool)(tlsf_t tlsf);
|
||||
pool_t (*tlsf_add_pool)(tlsf_t tlsf, void *mem, size_t bytes);
|
||||
void (*tlsf_remove_pool)(tlsf_t tlsf, pool_t pool);
|
||||
|
||||
void *(*tlsf_malloc)(tlsf_t tlsf, size_t size);
|
||||
void *(*tlsf_memalign)(tlsf_t tlsf, size_t align, size_t size);
|
||||
void *(*tlsf_memalign_offs)(tlsf_t tlsf, size_t align, size_t size, size_t offset);
|
||||
void *(*tlsf_realloc)(tlsf_t tlsf, void *ptr, size_t size);
|
||||
void (*tlsf_free)(tlsf_t tlsf, void *ptr);
|
||||
|
||||
size_t (*tlsf_block_size)(void *ptr);
|
||||
size_t (*tlsf_size)(tlsf_t tlsf);
|
||||
size_t (*tlsf_align_size)(void);
|
||||
size_t (*tlsf_block_size_min)(void);
|
||||
/* NOTE: The ROM signature is tlsf_block_size_max(control_t *control), but
|
||||
* control_t is an internal TLSF type not exposed in any public header.
|
||||
* Since tlsf_t is typedef'd as void* (same as control_t), the ABI is
|
||||
* identical and we use tlsf_t here to keep this header self-contained. */
|
||||
size_t (*tlsf_block_size_max)(tlsf_t tlsf);
|
||||
size_t (*tlsf_pool_overhead)(void);
|
||||
size_t (*tlsf_alloc_overhead)(void);
|
||||
|
||||
void (*tlsf_walk_pool)(pool_t pool, tlsf_walker walker, void *user);
|
||||
|
||||
int (*tlsf_check)(tlsf_t tlsf);
|
||||
int (*tlsf_check_pool)(pool_t pool);
|
||||
|
||||
void *(*tlsf_malloc_addr)(tlsf_t tlsf, size_t size, void *address);
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -43,6 +43,10 @@ config ESP_ROM_HAS_HEAP_TLSF
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_TLSF_CHECK_PATCH
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_MULTI_HEAP_WALK_PATCH
|
||||
bool
|
||||
default y
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#define ESP_ROM_HAS_HAL_SYSTIMER (1) // ROM has the implementation of Systimer HAL driver
|
||||
#define ESP_ROM_SYSTIMER_INIT_PATCH (1) // ROM version initializes SYSTIMER without ETM
|
||||
#define ESP_ROM_HAS_HEAP_TLSF (1) // ROM has the implementation of the tlsf and multi-heap library
|
||||
#define ESP_ROM_TLSF_CHECK_PATCH (1) // ROM does not contain the patch of tlsf_check_pool()
|
||||
#define ESP_ROM_MULTI_HEAP_WALK_PATCH (1) // ROM does not contain the patch of multi_heap_walk()
|
||||
#define ESP_ROM_HAS_LAYOUT_TABLE (1) // ROM has the layout table
|
||||
#define ESP_ROM_HAS_SPI_FLASH (1) // ROM has the implementation of SPI Flash driver
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include "esp_rom_tlsf.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief TLSF ROM vtable stub table for esp32h21.
|
||||
*
|
||||
* This struct mirrors the TLSF function-pointer vtable stored in ROM.
|
||||
* Its layout MUST exactly match the ROM vtable for the target chip.
|
||||
* It is used by tlsf_set_rom_patches() to intercept TLSF calls.
|
||||
*/
|
||||
struct heap_tlsf_stub_table_t {
|
||||
tlsf_t (*tlsf_create)(void *mem, size_t max_bytes);
|
||||
tlsf_t (*tlsf_create_with_pool)(void *mem, size_t pool_bytes, size_t max_bytes);
|
||||
pool_t (*tlsf_get_pool)(tlsf_t tlsf);
|
||||
pool_t (*tlsf_add_pool)(tlsf_t tlsf, void *mem, size_t bytes);
|
||||
void (*tlsf_remove_pool)(tlsf_t tlsf, pool_t pool);
|
||||
|
||||
void *(*tlsf_malloc)(tlsf_t tlsf, size_t size);
|
||||
void *(*tlsf_memalign)(tlsf_t tlsf, size_t align, size_t size);
|
||||
void *(*tlsf_memalign_offs)(tlsf_t tlsf, size_t align, size_t size, size_t offset);
|
||||
void *(*tlsf_realloc)(tlsf_t tlsf, void *ptr, size_t size);
|
||||
void (*tlsf_free)(tlsf_t tlsf, void *ptr);
|
||||
|
||||
size_t (*tlsf_block_size)(void *ptr);
|
||||
size_t (*tlsf_size)(tlsf_t tlsf);
|
||||
size_t (*tlsf_align_size)(void);
|
||||
size_t (*tlsf_block_size_min)(void);
|
||||
/* NOTE: The ROM signature is tlsf_block_size_max(control_t *control), but
|
||||
* control_t is an internal TLSF type not exposed in any public header.
|
||||
* Since tlsf_t is typedef'd as void* (same as control_t), the ABI is
|
||||
* identical and we use tlsf_t here to keep this header self-contained. */
|
||||
size_t (*tlsf_block_size_max)(tlsf_t tlsf);
|
||||
size_t (*tlsf_pool_overhead)(void);
|
||||
size_t (*tlsf_alloc_overhead)(void);
|
||||
|
||||
void (*tlsf_walk_pool)(pool_t pool, tlsf_walker walker, void *user);
|
||||
|
||||
int (*tlsf_check)(tlsf_t tlsf);
|
||||
int (*tlsf_check_pool)(pool_t pool);
|
||||
|
||||
void *(*tlsf_malloc_addr)(tlsf_t tlsf, size_t size, void *address);
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -43,6 +43,10 @@ config ESP_ROM_HAS_HEAP_TLSF
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_TLSF_CHECK_PATCH
|
||||
bool
|
||||
default y
|
||||
|
||||
config ESP_ROM_MULTI_HEAP_WALK_PATCH
|
||||
bool
|
||||
default y
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#define ESP_ROM_HAS_HAL_SYSTIMER (1) // ROM has the implementation of Systimer HAL driver
|
||||
#define ESP_ROM_SYSTIMER_INIT_PATCH (1) // ROM version initializes SYSTIMER without ETM
|
||||
#define ESP_ROM_HAS_HEAP_TLSF (1) // ROM has the implementation of the tlsf and multi-heap library
|
||||
#define ESP_ROM_TLSF_CHECK_PATCH (1) // ROM does not contain the patch of tlsf_check_pool()
|
||||
#define ESP_ROM_MULTI_HEAP_WALK_PATCH (1) // ROM does not contain the patch of multi_heap_walk()
|
||||
#define ESP_ROM_HAS_LAYOUT_TABLE (1) // ROM has the layout table
|
||||
#define ESP_ROM_WITHOUT_REGI2C (1) // ROM has the regi2c bug or rom does not support regi2c function
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include "esp_rom_tlsf.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief TLSF ROM vtable stub table for esp32h4.
|
||||
*
|
||||
* This struct mirrors the TLSF function-pointer vtable stored in ROM.
|
||||
* Its layout MUST exactly match the ROM vtable for the target chip.
|
||||
* It is used by tlsf_set_rom_patches() to intercept TLSF calls.
|
||||
*/
|
||||
struct heap_tlsf_stub_table_t {
|
||||
tlsf_t (*tlsf_create)(void *mem, size_t max_bytes);
|
||||
tlsf_t (*tlsf_create_with_pool)(void *mem, size_t pool_bytes, size_t max_bytes);
|
||||
pool_t (*tlsf_get_pool)(tlsf_t tlsf);
|
||||
pool_t (*tlsf_add_pool)(tlsf_t tlsf, void *mem, size_t bytes);
|
||||
void (*tlsf_remove_pool)(tlsf_t tlsf, pool_t pool);
|
||||
|
||||
void *(*tlsf_malloc)(tlsf_t tlsf, size_t size);
|
||||
void *(*tlsf_memalign)(tlsf_t tlsf, size_t align, size_t size);
|
||||
void *(*tlsf_memalign_offs)(tlsf_t tlsf, size_t align, size_t size, size_t offset);
|
||||
void *(*tlsf_realloc)(tlsf_t tlsf, void *ptr, size_t size);
|
||||
void (*tlsf_free)(tlsf_t tlsf, void *ptr);
|
||||
|
||||
size_t (*tlsf_block_size)(void *ptr);
|
||||
size_t (*tlsf_size)(tlsf_t tlsf);
|
||||
size_t (*tlsf_align_size)(void);
|
||||
size_t (*tlsf_block_size_min)(void);
|
||||
/* NOTE: The ROM signature is tlsf_block_size_max(control_t *control), but
|
||||
* control_t is an internal TLSF type not exposed in any public header.
|
||||
* Since tlsf_t is typedef'd as void* (same as control_t), the ABI is
|
||||
* identical and we use tlsf_t here to keep this header self-contained. */
|
||||
size_t (*tlsf_block_size_max)(tlsf_t tlsf);
|
||||
size_t (*tlsf_pool_overhead)(void);
|
||||
size_t (*tlsf_alloc_overhead)(void);
|
||||
|
||||
void (*tlsf_walk_pool)(pool_t pool, tlsf_walker walker, void *user);
|
||||
|
||||
int (*tlsf_check)(tlsf_t tlsf);
|
||||
int (*tlsf_check_pool)(pool_t pool);
|
||||
|
||||
void *(*tlsf_malloc_addr)(tlsf_t tlsf, size_t size, void *address);
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include "esp_rom_tlsf.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief TLSF ROM vtable stub table for esp32s31.
|
||||
*
|
||||
* This struct mirrors the TLSF function-pointer vtable stored in ROM.
|
||||
* Its layout MUST exactly match the ROM vtable for the target chip.
|
||||
* It is used by tlsf_set_rom_patches() to intercept TLSF calls.
|
||||
*/
|
||||
struct heap_tlsf_stub_table_t {
|
||||
tlsf_t (*tlsf_create)(void *mem, size_t max_bytes);
|
||||
tlsf_t (*tlsf_create_with_pool)(void *mem, size_t pool_bytes, size_t max_bytes);
|
||||
pool_t (*tlsf_get_pool)(tlsf_t tlsf);
|
||||
pool_t (*tlsf_add_pool)(tlsf_t tlsf, void *mem, size_t bytes);
|
||||
void (*tlsf_remove_pool)(tlsf_t tlsf, pool_t pool);
|
||||
|
||||
void *(*tlsf_malloc)(tlsf_t tlsf, size_t size);
|
||||
void *(*tlsf_memalign)(tlsf_t tlsf, size_t align, size_t size);
|
||||
void *(*tlsf_memalign_offs)(tlsf_t tlsf, size_t align, size_t size, size_t offset);
|
||||
void *(*tlsf_realloc)(tlsf_t tlsf, void *ptr, size_t size);
|
||||
void (*tlsf_free)(tlsf_t tlsf, void *ptr);
|
||||
|
||||
size_t (*tlsf_block_size)(void *ptr);
|
||||
size_t (*tlsf_size)(tlsf_t tlsf);
|
||||
size_t (*tlsf_align_size)(void);
|
||||
size_t (*tlsf_block_size_min)(void);
|
||||
/* NOTE: The ROM signature is tlsf_block_size_max(control_t *control), but
|
||||
* control_t is an internal TLSF type not exposed in any public header.
|
||||
* Since tlsf_t is typedef'd as void* (same as control_t), the ABI is
|
||||
* identical and we use tlsf_t here to keep this header self-contained. */
|
||||
size_t (*tlsf_block_size_max)(tlsf_t tlsf);
|
||||
size_t (*tlsf_pool_overhead)(void);
|
||||
size_t (*tlsf_alloc_overhead)(void);
|
||||
|
||||
void (*tlsf_walk_pool)(pool_t pool, tlsf_walker walker, void *user);
|
||||
|
||||
int (*tlsf_check)(tlsf_t tlsf);
|
||||
int (*tlsf_check_pool)(pool_t pool);
|
||||
|
||||
void *(*tlsf_malloc_addr)(tlsf_t tlsf, size_t size, void *address);
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -75,6 +75,7 @@ typedef bool (*tlsf_walker)(void* ptr, size_t size, int used, void* user);
|
||||
|
||||
/* Debugging. */
|
||||
void tlsf_walk_pool(pool_t pool, tlsf_walker walker, void* user);
|
||||
void tlsf_walk_pool_patched(pool_t pool, tlsf_walker walker, void* user);
|
||||
/* Returns nonzero if any internal consistency check fails. */
|
||||
int tlsf_check(tlsf_t tlsf);
|
||||
int tlsf_check_pool(pool_t pool);
|
||||
@@ -100,14 +101,23 @@ typedef bool (*poison_check_pfunc_t)(void *start, size_t size, bool is_free, boo
|
||||
void tlsf_poison_fill_pfunc_set(poison_fill_pfunc_t pfunc);
|
||||
|
||||
/*!
|
||||
* @brief Set the function to call for checking memory region when
|
||||
* poisoning is configured.
|
||||
* @brief Set the function to call in tlsf_check for checking memory
|
||||
* region when poisoning is configured.
|
||||
*
|
||||
* @param pfunc The callback function to trigger for checking
|
||||
* the content of a memory region.
|
||||
*/
|
||||
void tlsf_poison_check_pfunc_set(poison_check_pfunc_t pfunc);
|
||||
|
||||
/*!
|
||||
* @brief Set the function to call in tlsf_walk_pool for checking memory
|
||||
* region when poisoning is configured.
|
||||
*
|
||||
* @param pfunc The callback function to trigger for checking
|
||||
* the content of a memory region.
|
||||
*/
|
||||
void tlsf_walk_pool_pfunc_set(poison_check_pfunc_t pfunc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -16,19 +16,13 @@
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_rom_multi_heap.h"
|
||||
#include "esp_rom_tlsf.h"
|
||||
|
||||
// Hook to force the linker to include this file
|
||||
void esp_rom_include_multi_heap_patch(void)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Opaque types for TLSF implementation
|
||||
*/
|
||||
typedef void* tlsf_t;
|
||||
typedef void* pool_t;
|
||||
typedef void* tlsf_walker;
|
||||
|
||||
typedef struct multi_heap_info {
|
||||
void *lock;
|
||||
size_t free_bytes;
|
||||
@@ -37,7 +31,7 @@ typedef struct multi_heap_info {
|
||||
void* heap_data;
|
||||
} heap_t;
|
||||
|
||||
extern void tlsf_walk_pool(pool_t pool, tlsf_walker walker, void* user);
|
||||
/* Declare helper functions that are not in public headers */
|
||||
extern pool_t tlsf_get_pool(tlsf_t tlsf);
|
||||
extern void multi_heap_internal_lock(multi_heap_handle_t heap);
|
||||
extern void multi_heap_internal_unlock(multi_heap_handle_t heap);
|
||||
@@ -47,7 +41,7 @@ void multi_heap_walk(multi_heap_handle_t heap, multi_heap_walker_cb_t walker_fun
|
||||
assert(heap != NULL);
|
||||
|
||||
multi_heap_internal_lock(heap);
|
||||
tlsf_walk_pool(tlsf_get_pool(heap->heap_data), walker_func, user_data);
|
||||
tlsf_walk_pool_patched(tlsf_get_pool(heap->heap_data), walker_func, user_data);
|
||||
multi_heap_internal_unlock(heap);
|
||||
}
|
||||
|
||||
@@ -129,10 +123,11 @@ void* tlsf_find_containing_block(pool_t pool, void *ptr)
|
||||
while (block && !block_is_last(block))
|
||||
{
|
||||
if (!block_is_free(block)) {
|
||||
void *block_end = block_to_ptr(block) + block_size(block);
|
||||
if (block_to_ptr(block) <= ptr && block_end > ptr) {
|
||||
void *block_start = block_to_ptr(block);
|
||||
void *block_end = block_start + block_size(block);
|
||||
if (block_start <= ptr && block_end > ptr) {
|
||||
// we found the containing block, return
|
||||
return block_to_ptr(block);
|
||||
return block_start;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -20,15 +20,51 @@
|
||||
|
||||
#include "esp_rom_caps.h"
|
||||
#include "esp_rom_tlsf.h"
|
||||
#include "esp_rom_sys.h"
|
||||
|
||||
#include "tlsf_block_functions.h"
|
||||
#include "tlsf_control_functions.h"
|
||||
|
||||
static poison_check_pfunc_t s_poison_check_region = NULL;
|
||||
/*
|
||||
* IMPORTANT!
|
||||
*
|
||||
* Several versions of the TLSF in ROM exist and can be divided in
|
||||
* 3 categories:
|
||||
* 1- Versions where tlsf_check and tlsf_walk_pool do not call
|
||||
* the poison check hook (oldest versions)
|
||||
* 2- Versions where tlsf_check does call the poison check hook,
|
||||
* but tlsf_walk_pool still doesn't (intermediate versions)
|
||||
* 3- Versions where both tlsf_check and tlsf_walk_pool call the
|
||||
* the poison check hook (latest versions)
|
||||
*
|
||||
* Category 3 does not require the patch defined in this file.
|
||||
*
|
||||
* Category 2 requires the patch but only for tlsf_walk_pool. In those
|
||||
* versions, a definition of tlsf_poison_check_pfunc_set is present in
|
||||
* the TLSF ROM which makes the definition in this file unnecessary since
|
||||
* the linker will keep the ROM definition. For this reason, tlsf_walk_pool_pfunc_set
|
||||
* is defined and called in multi_heap_poisoning.c to make sure that the poison check
|
||||
* hook also gets set in this file. The definition of tlsf_poison_check_pfunc_set could
|
||||
* be removed from this file if not for the needs of category 1.
|
||||
*
|
||||
* Category 1 versions of the ROM TLSF do not provide a definition of
|
||||
* tlsf_poison_check_pfunc_set, making the definition below necessary for
|
||||
* any application to compile and link properly. The added patch of tlsf_walk_pool
|
||||
* makes the patch of tlsf_check unnecessary in this file since tlsf_check was only
|
||||
* calling the poison check hook for free blocks while tlsf_walk_pool calls the poison
|
||||
* check hook for all blocks (free and used). For this reason, tlsf_poison_check_pfunc_set
|
||||
* is left empty.
|
||||
* */
|
||||
|
||||
static poison_check_pfunc_t s_walk_pool_check_region = NULL;
|
||||
|
||||
void tlsf_poison_check_pfunc_set(poison_check_pfunc_t pfunc)
|
||||
{
|
||||
s_poison_check_region = pfunc;
|
||||
}
|
||||
|
||||
void tlsf_walk_pool_pfunc_set(poison_check_pfunc_t pfunc)
|
||||
{
|
||||
s_walk_pool_check_region = pfunc;
|
||||
}
|
||||
|
||||
#define tlsf_insist_no_assert(x) { if (!(x)) { status--; } }
|
||||
@@ -51,7 +87,7 @@ static bool integrity_walker(void* ptr, size_t size, int used, void* user)
|
||||
tlsf_insist_no_assert(integ->prev_status == this_prev_status && "prev status incorrect");
|
||||
tlsf_insist_no_assert(size == this_block_size && "block size incorrect");
|
||||
|
||||
if (s_poison_check_region != NULL)
|
||||
if (s_walk_pool_check_region != NULL)
|
||||
{
|
||||
/* block_size(block) returns the size of the usable memory when the block is allocated.
|
||||
* As the block under test is free, we need to subtract to the block size the next_free
|
||||
@@ -66,7 +102,7 @@ static bool integrity_walker(void* ptr, size_t size, int used, void* user)
|
||||
void* ptr_block = used ? (void*)block + block_start_offset :
|
||||
(void*)block + sizeof(block_header_t);
|
||||
|
||||
tlsf_insist_no_assert(s_poison_check_region(ptr_block, actual_free_block_size, !used, true));
|
||||
tlsf_insist_no_assert(s_walk_pool_check_region(ptr_block, actual_free_block_size, !used, true));
|
||||
}
|
||||
|
||||
integ->prev_status = this_status;
|
||||
@@ -82,7 +118,7 @@ static bool default_walker(void* ptr, size_t size, int used, void* user)
|
||||
return true;
|
||||
}
|
||||
|
||||
void tlsf_walk_pool(pool_t pool, tlsf_walker walker, void* user)
|
||||
static void tlsf_walk_pool_impl(pool_t pool, tlsf_walker walker, void* user)
|
||||
{
|
||||
tlsf_walker pool_walker = walker ? walker : default_walker;
|
||||
block_header_t* block =
|
||||
@@ -103,11 +139,11 @@ void tlsf_walk_pool(pool_t pool, tlsf_walker walker, void* user)
|
||||
}
|
||||
}
|
||||
|
||||
int tlsf_check_pool(pool_t pool)
|
||||
static int tlsf_check_pool_impl(pool_t pool)
|
||||
{
|
||||
/* Check that the blocks are physically correct. */
|
||||
integrity_t integ = { 0, 0 };
|
||||
tlsf_walk_pool(pool, integrity_walker, &integ);
|
||||
tlsf_walk_pool_impl(pool, integrity_walker, &integ);
|
||||
|
||||
return integ.status;
|
||||
}
|
||||
@@ -116,38 +152,13 @@ int tlsf_check_pool(pool_t pool)
|
||||
|
||||
/* Set up the TLSF ROM patches here */
|
||||
|
||||
/*!
|
||||
* @brief Structure to store all the functions of a TLSF implementation.
|
||||
* The goal of this table is to change any of the address here in order
|
||||
* to let the ROM code call another function implementation than the one
|
||||
* in ROM.
|
||||
/*
|
||||
* struct heap_tlsf_stub_table_t is defined in the per-target header.
|
||||
* Its layout exactly mirrors the TLSF vtable in ROM for the current target.
|
||||
* The header is produced by gen_esp_rom_heap_tlsf_stub_table.py from the
|
||||
* target's .rom.heap.ld file; run that script whenever the .ld file changes.
|
||||
*/
|
||||
struct heap_tlsf_stub_table_t {
|
||||
tlsf_t (*tlsf_create)(void* mem);
|
||||
tlsf_t (*tlsf_create_with_pool)(void* mem, size_t bytes);
|
||||
pool_t (*tlsf_get_pool)(tlsf_t tlsf);
|
||||
pool_t (*tlsf_add_pool)(tlsf_t tlsf, void* mem, size_t bytes);
|
||||
void (*tlsf_remove_pool)(tlsf_t tlsf, pool_t pool);
|
||||
|
||||
void* (*tlsf_malloc)(tlsf_t tlsf, size_t size);
|
||||
void* (*tlsf_memalign)(tlsf_t tlsf, size_t align, size_t size);
|
||||
void* (*tlsf_memalign_offs)(tlsf_t tlsf, size_t align, size_t size, size_t offset);
|
||||
void* (*tlsf_realloc)(tlsf_t tlsf, void* ptr, size_t size);
|
||||
void (*tlsf_free)(tlsf_t tlsf, void* ptr);
|
||||
|
||||
size_t (*tlsf_block_size)(void* ptr);
|
||||
size_t (*tlsf_size)(void);
|
||||
size_t (*tlsf_align_size)(void);
|
||||
size_t (*tlsf_block_size_min)(void);
|
||||
size_t (*tlsf_block_size_max)(void);
|
||||
size_t (*tlsf_pool_overhead)(void);
|
||||
size_t (*tlsf_alloc_overhead)(void);
|
||||
|
||||
void (*tlsf_walk_pool)(pool_t pool, tlsf_walker walker, void* user);
|
||||
|
||||
int (*tlsf_check)(tlsf_t tlsf);
|
||||
int (*tlsf_check_pool)(pool_t pool);
|
||||
};
|
||||
#include "esp_rom_heap_tlsf_stub_table.h"
|
||||
|
||||
/* We need the original table from the ROM */
|
||||
extern struct heap_tlsf_stub_table_t* heap_tlsf_table_ptr;
|
||||
@@ -169,8 +180,20 @@ void __attribute__((constructor)) tlsf_set_rom_patches(void)
|
||||
memcpy(&heap_tlsf_patch_table_ptr, heap_tlsf_table_ptr, sizeof(struct heap_tlsf_stub_table_t));
|
||||
|
||||
/* Set the patched function here */
|
||||
heap_tlsf_patch_table_ptr.tlsf_check_pool = tlsf_check_pool;
|
||||
heap_tlsf_patch_table_ptr.tlsf_check_pool = tlsf_check_pool_impl;
|
||||
heap_tlsf_patch_table_ptr.tlsf_walk_pool = tlsf_walk_pool_impl;
|
||||
|
||||
/* Set our table as the one to use in the ROM code */
|
||||
heap_tlsf_table_ptr = &heap_tlsf_patch_table_ptr;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Helper function to call the patched tlsf_walk_pool.
|
||||
* This is needed because the ROM's tlsf_walk_pool symbol cannot be overridden
|
||||
* on chips where it's a strong symbol (not using PROVIDE in linker script).
|
||||
* Other patch files can call this to access the patched version.
|
||||
*/
|
||||
void tlsf_walk_pool_patched(pool_t pool, tlsf_walker walker, void* user)
|
||||
{
|
||||
heap_tlsf_table_ptr->tlsf_walk_pool(pool, walker, user);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user