mirror of
https://github.com/apache/nuttx.git
synced 2026-05-22 22:20:01 +08:00
arch/sim: Implement text heap
If CONFIG_MM_CUSTOMIZE_MANAGER enabled on sim, malloc/mmap is bypassed to glibc, so the memory allocated without execution permisson. For this case, CONFIG_ARCH_USE_TEXT_HEAP can be used. Signed-off-by: Huang Qi <huangqi3@xiaomi.com>
This commit is contained in:
@@ -103,6 +103,7 @@ config ARCH_SIM
|
||||
select ARCH_HAVE_VFORK if !HOST_WINDOWS
|
||||
select ARCH_HAVE_SETJMP
|
||||
select ARCH_HAVE_CUSTOMOPT
|
||||
select ARCH_HAVE_TEXT_HEAP
|
||||
select ARCH_SETJMP_H
|
||||
select ALARM_ARCH
|
||||
select ONESHOT
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <malloc/malloc.h>
|
||||
@@ -47,6 +48,18 @@
|
||||
static atomic_int g_aordblks;
|
||||
static atomic_int g_uordblks;
|
||||
|
||||
/* Record memory allocated for text sections by sys/queue.h */
|
||||
|
||||
struct textheap_s
|
||||
{
|
||||
void *p;
|
||||
size_t size;
|
||||
TAILQ_ENTRY(textheap_s) entry;
|
||||
};
|
||||
|
||||
static TAILQ_HEAD(, textheap_s) g_textheap_list =
|
||||
TAILQ_HEAD_INITIALIZER(g_textheap_list);
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@@ -54,6 +67,104 @@ static atomic_int g_uordblks;
|
||||
extern uint64_t up_irq_save(void);
|
||||
extern void up_irq_restore(uint64_t flags);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_textheap_memalign
|
||||
*
|
||||
* Description:
|
||||
* Allocate memory for text sections with the specified alignment.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void *up_textheap_memalign(size_t align, size_t size)
|
||||
{
|
||||
uint64_t flags;
|
||||
void *p;
|
||||
|
||||
/* host_allocheap (mmap) returns memory aligned to the page size, which
|
||||
* is always a multiple of the alignment (4/8) for text section. So, we
|
||||
* don't need to do anything here.
|
||||
*/
|
||||
|
||||
p = host_allocheap(size);
|
||||
|
||||
flags = up_irq_save();
|
||||
|
||||
/* Record the allocated memory to a global list */
|
||||
|
||||
if (p)
|
||||
{
|
||||
struct textheap_s *node = malloc(sizeof(struct textheap_s));
|
||||
if (node)
|
||||
{
|
||||
node->p = p;
|
||||
node->size = size;
|
||||
TAILQ_INSERT_TAIL(&g_textheap_list, node, entry);
|
||||
}
|
||||
}
|
||||
|
||||
up_irq_restore(flags);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_textheap_free
|
||||
*
|
||||
* Description:
|
||||
* Free memory allocated for text sections.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void up_textheap_free(void *p)
|
||||
{
|
||||
struct textheap_s *node;
|
||||
uint64_t flags = up_irq_save();
|
||||
|
||||
/* Remove the memory from the global list */
|
||||
|
||||
TAILQ_FOREACH(node, &g_textheap_list, entry)
|
||||
{
|
||||
if (node->p == p)
|
||||
{
|
||||
TAILQ_REMOVE(&g_textheap_list, node, entry);
|
||||
free(node);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
up_irq_restore(flags);
|
||||
host_freeheap(p);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_textheap_heapmember
|
||||
*
|
||||
* Description:
|
||||
* Test if memory is from text heap.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
bool up_textheap_heapmember(void *p)
|
||||
{
|
||||
struct textheap_s *node;
|
||||
uint64_t flags = up_irq_save();
|
||||
|
||||
/* Traverse the global list to find the memory */
|
||||
|
||||
TAILQ_FOREACH(node, &g_textheap_list, entry)
|
||||
{
|
||||
if (node->p == p)
|
||||
{
|
||||
up_irq_restore(flags);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
up_irq_restore(flags);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: host_allocheap
|
||||
*
|
||||
@@ -87,6 +198,21 @@ void *host_allocheap(size_t sz)
|
||||
return p;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: host_freeheap
|
||||
*
|
||||
* Description:
|
||||
* Free a executable memory block.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void host_freeheap(void *mem)
|
||||
{
|
||||
uint64_t flags = up_irq_save();
|
||||
munmap(mem, 0);
|
||||
up_irq_restore(flags);
|
||||
}
|
||||
|
||||
void *host_allocshmem(const char *name, size_t size, int master)
|
||||
{
|
||||
uint64_t flags = up_irq_save();
|
||||
|
||||
@@ -171,6 +171,7 @@ void host_init_cwd(void);
|
||||
/* sim_hostmemory.c *********************************************************/
|
||||
|
||||
void *host_allocheap(size_t sz);
|
||||
void host_freeheap(void *mem);
|
||||
void *host_allocshmem(const char *name, size_t size, int master);
|
||||
void host_freeshmem(void *mem);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user