Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions arch/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -670,6 +670,14 @@ config ARCH_USE_DATA_HEAP
This option enables architecture-specific memory allocator
for dynamic data loading.

config ARCH_USE_SEPARATED_SECTION
bool "Enable separate section allocation for dynamic loading"
default n
depends on ARCH_USE_TEXT_HEAP || ARCH_USE_DATA_HEAP
---help---
This option enables loading different sections into different
memory areas, allowing for different speeds.

menuconfig ARCH_ADDRENV
bool "Address environments"
default n
Expand Down
2 changes: 1 addition & 1 deletion arch/sim/src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ CSRCS = sim_initialize.c sim_idle.c sim_doirq.c sim_initialstate.c
CSRCS += sim_createstack.c sim_usestack.c sim_releasestack.c sim_stackframe.c
CSRCS += sim_exit.c sim_schedulesigaction.c sim_switchcontext.c sim_heap.c
CSRCS += sim_uart.c sim_copyfullstate.c sim_sigdeliver.c sim_tcbinfo.c sim_cpuinfo.c
CSRCS += sim_registerdump.c sim_saveusercontext.c sim_textheap.c
CSRCS += sim_registerdump.c sim_saveusercontext.c sim_sectionheap.c
CSRCS += sim_checkhostfstypes.c

ifeq ($(CONFIG_SCHED_BACKTRACE),y)
Expand Down
2 changes: 1 addition & 1 deletion arch/sim/src/sim/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ list(
sim_registerdump.c
sim_saveusercontext.c
sim_tcbinfo.c
sim_textheap.c
sim_sectionheap.c
sim_checkhostfstypes.c)

if(CONFIG_HOST_X86_64)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/****************************************************************************
* arch/sim/src/sim/sim_textheap.c
* arch/sim/src/sim/sim_sectionheap.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
Expand Down Expand Up @@ -32,6 +32,7 @@
****************************************************************************/

static struct mm_heap_s *g_textheap;
static struct mm_heap_s *g_dataheap;

/****************************************************************************
* Public Functions
Expand All @@ -45,7 +46,11 @@ static struct mm_heap_s *g_textheap;
*
****************************************************************************/

#ifdef CONFIG_ARCH_USE_SEPARATED_SECTION
void *up_textheap_memalign(const char *sectname, size_t align, size_t size)
#else
void *up_textheap_memalign(size_t align, size_t size)
#endif
{
if (g_textheap == NULL)
{
Expand Down Expand Up @@ -85,3 +90,56 @@ bool up_textheap_heapmember(void *p)
{
return g_textheap != NULL && mm_heapmember(g_textheap, p);
}

/****************************************************************************
* Name: up_dataheap_memalign
*
* Description:
* Allocate memory for data sections with the specified alignment.
*
****************************************************************************/

#ifdef CONFIG_ARCH_USE_SEPARATED_SECTION
void *up_dataheap_memalign(const char *sectname, size_t align, size_t size)
#else
void *up_dataheap_memalign(size_t align, size_t size)
#endif
{
if (g_dataheap == NULL)
{
g_dataheap = mm_initialize("dataheap",
host_allocheap(SIM_HEAP_SIZE, true),
SIM_HEAP_SIZE);
}

return mm_memalign(g_dataheap, align, size);
}

/****************************************************************************
* Name: up_dataheap_free
*
* Description:
* Free memory allocated for data sections.
*
****************************************************************************/

void up_dataheap_free(void *p)
{
if (g_dataheap != NULL)
{
mm_free(g_dataheap, p);
}
}

/****************************************************************************
* Name: up_dataheap_heapmember
*
* Description:
* Test if memory is from data heap.
*
****************************************************************************/

bool up_dataheap_heapmember(void *p)
{
return g_dataheap != NULL && mm_heapmember(g_dataheap, p);
}
34 changes: 34 additions & 0 deletions binfmt/binfmt_unloadmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,33 @@ int unload_module(FAR struct binary_s *binp)
file_munmap(binp->mapped, binp->mapsize);
}

#ifdef CONFIG_ARCH_USE_SEPARATED_SECTION
for (i = 0; binp->sectalloc[i] != NULL && i < binp->nsect; i++)
{
# ifdef CONFIG_ARCH_USE_TEXT_HEAP
if (up_textheap_heapmember(binp->sectalloc[i]))
{
up_textheap_free(binp->sectalloc[i]);
}
else
# endif

# ifdef CONFIG_ARCH_USE_DATA_HEAP
if (up_dataheap_heapmember(binp->sectalloc[i]))
{
up_dataheap_free(binp->sectalloc[i]);
}
else
# endif
{
kumm_free(binp->sectalloc[i]);
}
}

binp->alloc[0] = NULL;
binp->alloc[1] = NULL;
#endif

/* Free allocated address spaces */

for (i = 0; i < BINFMT_NALLOC; i++)
Expand All @@ -174,6 +201,13 @@ int unload_module(FAR struct binary_s *binp)
up_textheap_free(binp->alloc[i]);
}
else
#endif
#if defined(CONFIG_ARCH_USE_DATA_HEAP)
if (i == 1)
{
up_dataheap_free(binp->alloc[i]);
}
else
#endif
{
kumm_free(binp->alloc[i]);
Expand Down
16 changes: 16 additions & 0 deletions binfmt/elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,14 @@ static void elf_dumploadinfo(FAR struct elf_loadinfo_s *loadinfo)
for (i = 0; i < loadinfo->ehdr.e_shnum; i++)
{
FAR Elf_Shdr *shdr = &loadinfo->shdr[i];
# ifdef CONFIG_ARCH_USE_SEPARATED_SECTION
if (loadinfo->ehdr.e_type == ET_REL)
{
binfo(" sh_alloc: %08jx\n",
(uintmax_t)loadinfo->sectalloc[i]);
}
# endif

binfo("Sections %d:\n", i);
binfo(" sh_name: %08x\n", shdr->sh_name);
binfo(" sh_type: %08x\n", shdr->sh_type);
Expand Down Expand Up @@ -317,6 +325,14 @@ static int elf_loadbinary(FAR struct binary_s *binp,
binp->addrenv = loadinfo.addrenv;

#else
# ifdef CONFIG_ARCH_USE_SEPARATED_SECTION
if (loadinfo.ehdr.e_type == ET_REL)
{
binp->sectalloc = (FAR void *)loadinfo.sectalloc;
binp->nsect = loadinfo.ehdr.e_shnum;
}
# endif

binp->alloc[0] = (FAR void *)loadinfo.textalloc;
binp->alloc[1] = (FAR void *)loadinfo.dataalloc;
# ifdef CONFIG_BINFMT_CONSTRUCTORS
Expand Down
62 changes: 49 additions & 13 deletions binfmt/libelf/libelf_addrenv.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,15 @@ int elf_addrenv_alloc(FAR struct elf_loadinfo_s *loadinfo, size_t textsize,

/* Allocate memory to hold the ELF image */

# if defined(CONFIG_ARCH_USE_TEXT_HEAP)
# ifndef CONFIG_ARCH_USE_SEPARATED_SECTION
# if defined(CONFIG_ARCH_USE_TEXT_HEAP)
loadinfo->textalloc = (uintptr_t)
up_textheap_memalign(loadinfo->textalign, textsize);
# else
up_textheap_memalign(loadinfo->textalign,
textsize);
# else
loadinfo->textalloc = (uintptr_t)
kumm_memalign(loadinfo->textalign, textsize);
# endif
# endif

if (!loadinfo->textalloc)
{
Expand All @@ -161,19 +163,20 @@ int elf_addrenv_alloc(FAR struct elf_loadinfo_s *loadinfo, size_t textsize,

if (loadinfo->datasize > 0)
{
# if defined(CONFIG_ARCH_USE_DATA_HEAP)
# ifdef CONFIG_ARCH_USE_DATA_HEAP
loadinfo->dataalloc = (uintptr_t)
up_dataheap_memalign(loadinfo->dataalign,
datasize);
# else
# else
loadinfo->dataalloc = (uintptr_t)
kumm_memalign(loadinfo->dataalign, datasize);
# endif
# endif
if (!loadinfo->dataalloc)
{
return -ENOMEM;
}
}
# endif

return OK;
#endif
Expand Down Expand Up @@ -290,23 +293,56 @@ void elf_addrenv_free(FAR struct elf_loadinfo_s *loadinfo)
addrenv_drop(loadinfo->addrenv, false);
#else

# ifndef CONFIG_ARCH_USE_SEPARATED_SECTION
if (loadinfo->textalloc != 0)
{
# if defined(CONFIG_ARCH_USE_TEXT_HEAP)
# if defined(CONFIG_ARCH_USE_TEXT_HEAP)
up_textheap_free((FAR void *)loadinfo->textalloc);
# else
# else
kumm_free((FAR void *)loadinfo->textalloc);
# endif
# endif
}

if (loadinfo->dataalloc != 0)
{
# if defined(CONFIG_ARCH_USE_DATA_HEAP)
# if defined(CONFIG_ARCH_USE_DATA_HEAP)
up_dataheap_free((FAR void *)loadinfo->dataalloc);
# else
# else
kumm_free((FAR void *)loadinfo->dataalloc);
# endif
# endif
}
# else
int i;

for (i = 0; loadinfo->ehdr.e_type == ET_REL && i < loadinfo->ehdr.e_shnum;
i++)
{
if (loadinfo->sectalloc[i] == 0)
{
continue;
}

if ((loadinfo->shdr[i].sh_flags & SHF_WRITE) != 0)
{
# if defined(CONFIG_ARCH_USE_DATA_HEAP)
up_dataheap_free((FAR void *)loadinfo->sectalloc[i]);
# else
kumm_free((FAR void *)loadinfo->sectalloc[i]);
# endif
}
else
{
# if defined(CONFIG_ARCH_USE_TEXT_HEAP)
up_textheap_free((FAR void *)loadinfo->sectalloc[i]);
# else
kumm_free((FAR void *)loadinfo->sectalloc[i]);
# endif
}
}

kmm_free(loadinfo->sectalloc);
loadinfo->sectalloc = 0;
# endif
#endif

/* Clear out all indications of the allocated address environment */
Expand Down
24 changes: 22 additions & 2 deletions binfmt/libelf/libelf_bind.c
Original file line number Diff line number Diff line change
Expand Up @@ -674,8 +674,28 @@ int elf_bind(FAR struct elf_loadinfo_s *loadinfo,
* contents to memory and invalidating the I cache).
*/

up_coherent_dcache(loadinfo->textalloc, loadinfo->textsize);
up_coherent_dcache(loadinfo->dataalloc, loadinfo->datasize);
if (loadinfo->textsize > 0)
{
up_coherent_dcache(loadinfo->textalloc, loadinfo->textsize);
}

if (loadinfo->datasize > 0)
{
up_coherent_dcache(loadinfo->dataalloc, loadinfo->datasize);
}

# ifdef CONFIG_ARCH_USE_SEPARATED_SECTION
for (i = 0; loadinfo->ehdr.e_type == ET_REL && i < loadinfo->ehdr.e_shnum;
i++)
{
if (loadinfo->sectalloc[i] == 0)
{
continue;
}

up_coherent_dcache(loadinfo->sectalloc[i], loadinfo->shdr[i].sh_size);
}
# endif

#endif

Expand Down
Loading