binfmt/modlib: support loading each sections to different memory for Relocate object
The feature depends on ARCH_USE_SEPARATED_SECTION the different memory area has different access speed and cache capability, so the arch can custom allocate them based on section names to achieve performance optimization test: sim:elf sim:sotest Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
This commit is contained in:
parent
a965e3c3f9
commit
3b0e2be058
@ -670,6 +670,14 @@ config ARCH_USE_DATA_HEAP
|
|||||||
This option enables architecture-specific memory allocator
|
This option enables architecture-specific memory allocator
|
||||||
for dynamic data loading.
|
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
|
menuconfig ARCH_ADDRENV
|
||||||
bool "Address environments"
|
bool "Address environments"
|
||||||
default n
|
default n
|
||||||
|
@ -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_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_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_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
|
CSRCS += sim_checkhostfstypes.c
|
||||||
|
|
||||||
ifeq ($(CONFIG_SCHED_BACKTRACE),y)
|
ifeq ($(CONFIG_SCHED_BACKTRACE),y)
|
||||||
|
@ -57,7 +57,7 @@ list(
|
|||||||
sim_registerdump.c
|
sim_registerdump.c
|
||||||
sim_saveusercontext.c
|
sim_saveusercontext.c
|
||||||
sim_tcbinfo.c
|
sim_tcbinfo.c
|
||||||
sim_textheap.c
|
sim_sectionheap.c
|
||||||
sim_checkhostfstypes.c)
|
sim_checkhostfstypes.c)
|
||||||
|
|
||||||
if(CONFIG_HOST_X86_64)
|
if(CONFIG_HOST_X86_64)
|
||||||
|
@ -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
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
@ -32,6 +32,7 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static struct mm_heap_s *g_textheap;
|
static struct mm_heap_s *g_textheap;
|
||||||
|
static struct mm_heap_s *g_dataheap;
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
@ -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)
|
void *up_textheap_memalign(size_t align, size_t size)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
if (g_textheap == NULL)
|
if (g_textheap == NULL)
|
||||||
{
|
{
|
||||||
@ -85,3 +90,56 @@ bool up_textheap_heapmember(void *p)
|
|||||||
{
|
{
|
||||||
return g_textheap != NULL && mm_heapmember(g_textheap, 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);
|
||||||
|
}
|
@ -161,6 +161,32 @@ int unload_module(FAR struct binary_s *binp)
|
|||||||
file_munmap(binp->mapped, binp->mapsize);
|
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]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifdef CONFIG_ARCH_USE_DATA_HEAP
|
||||||
|
if (up_dataheap_heapmember(binp->sectalloc[i]))
|
||||||
|
{
|
||||||
|
up_dataheap_free(binp->sectalloc[i]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
kumm_free(binp->sectalloc[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
binp->alloc[0] = NULL;
|
||||||
|
binp->alloc[1] = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Free allocated address spaces */
|
/* Free allocated address spaces */
|
||||||
|
|
||||||
for (i = 0; i < BINFMT_NALLOC; i++)
|
for (i = 0; i < BINFMT_NALLOC; i++)
|
||||||
@ -174,6 +200,13 @@ int unload_module(FAR struct binary_s *binp)
|
|||||||
up_textheap_free(binp->alloc[i]);
|
up_textheap_free(binp->alloc[i]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
|
#if defined(CONFIG_ARCH_USE_DATA_HEAP)
|
||||||
|
if (i == 1)
|
||||||
|
{
|
||||||
|
up_dataheap_free(binp->alloc[i]);
|
||||||
|
}
|
||||||
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
kumm_free(binp->alloc[i]);
|
kumm_free(binp->alloc[i]);
|
||||||
|
16
binfmt/elf.c
16
binfmt/elf.c
@ -164,6 +164,14 @@ static void elf_dumploadinfo(FAR struct elf_loadinfo_s *loadinfo)
|
|||||||
for (i = 0; i < loadinfo->ehdr.e_shnum; i++)
|
for (i = 0; i < loadinfo->ehdr.e_shnum; i++)
|
||||||
{
|
{
|
||||||
FAR Elf_Shdr *shdr = &loadinfo->shdr[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("Sections %d:\n", i);
|
||||||
binfo(" sh_name: %08x\n", shdr->sh_name);
|
binfo(" sh_name: %08x\n", shdr->sh_name);
|
||||||
binfo(" sh_type: %08x\n", shdr->sh_type);
|
binfo(" sh_type: %08x\n", shdr->sh_type);
|
||||||
@ -317,6 +325,14 @@ static int elf_loadbinary(FAR struct binary_s *binp,
|
|||||||
binp->addrenv = loadinfo.addrenv;
|
binp->addrenv = loadinfo.addrenv;
|
||||||
|
|
||||||
#else
|
#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[0] = (FAR void *)loadinfo.textalloc;
|
||||||
binp->alloc[1] = (FAR void *)loadinfo.dataalloc;
|
binp->alloc[1] = (FAR void *)loadinfo.dataalloc;
|
||||||
# ifdef CONFIG_BINFMT_CONSTRUCTORS
|
# ifdef CONFIG_BINFMT_CONSTRUCTORS
|
||||||
|
@ -146,13 +146,15 @@ errout_with_addrenv:
|
|||||||
|
|
||||||
/* Allocate memory to hold the ELF image */
|
/* 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)
|
loadinfo->textalloc = (uintptr_t)
|
||||||
up_textheap_memalign(loadinfo->textalign, textsize);
|
up_textheap_memalign(loadinfo->textalign,
|
||||||
# else
|
textsize);
|
||||||
|
# else
|
||||||
loadinfo->textalloc = (uintptr_t)
|
loadinfo->textalloc = (uintptr_t)
|
||||||
kumm_memalign(loadinfo->textalign, textsize);
|
kumm_memalign(loadinfo->textalign, textsize);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
if (!loadinfo->textalloc)
|
if (!loadinfo->textalloc)
|
||||||
{
|
{
|
||||||
@ -161,19 +163,20 @@ errout_with_addrenv:
|
|||||||
|
|
||||||
if (loadinfo->datasize > 0)
|
if (loadinfo->datasize > 0)
|
||||||
{
|
{
|
||||||
# if defined(CONFIG_ARCH_USE_DATA_HEAP)
|
# ifdef CONFIG_ARCH_USE_DATA_HEAP
|
||||||
loadinfo->dataalloc = (uintptr_t)
|
loadinfo->dataalloc = (uintptr_t)
|
||||||
up_dataheap_memalign(loadinfo->dataalign,
|
up_dataheap_memalign(loadinfo->dataalign,
|
||||||
datasize);
|
datasize);
|
||||||
# else
|
# else
|
||||||
loadinfo->dataalloc = (uintptr_t)
|
loadinfo->dataalloc = (uintptr_t)
|
||||||
kumm_memalign(loadinfo->dataalign, datasize);
|
kumm_memalign(loadinfo->dataalign, datasize);
|
||||||
# endif
|
# endif
|
||||||
if (!loadinfo->dataalloc)
|
if (!loadinfo->dataalloc)
|
||||||
{
|
{
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
#endif
|
#endif
|
||||||
@ -290,23 +293,56 @@ void elf_addrenv_free(FAR struct elf_loadinfo_s *loadinfo)
|
|||||||
addrenv_drop(loadinfo->addrenv, false);
|
addrenv_drop(loadinfo->addrenv, false);
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
# ifndef CONFIG_ARCH_USE_SEPARATED_SECTION
|
||||||
if (loadinfo->textalloc != 0)
|
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);
|
up_textheap_free((FAR void *)loadinfo->textalloc);
|
||||||
# else
|
# else
|
||||||
kumm_free((FAR void *)loadinfo->textalloc);
|
kumm_free((FAR void *)loadinfo->textalloc);
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loadinfo->dataalloc != 0)
|
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);
|
up_dataheap_free((FAR void *)loadinfo->dataalloc);
|
||||||
# else
|
# else
|
||||||
kumm_free((FAR void *)loadinfo->dataalloc);
|
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
|
#endif
|
||||||
|
|
||||||
/* Clear out all indications of the allocated address environment */
|
/* Clear out all indications of the allocated address environment */
|
||||||
|
@ -674,8 +674,28 @@ int elf_bind(FAR struct elf_loadinfo_s *loadinfo,
|
|||||||
* contents to memory and invalidating the I cache).
|
* contents to memory and invalidating the I cache).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
up_coherent_dcache(loadinfo->textalloc, loadinfo->textsize);
|
if (loadinfo->textsize > 0)
|
||||||
up_coherent_dcache(loadinfo->dataalloc, loadinfo->datasize);
|
{
|
||||||
|
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
|
#endif
|
||||||
|
|
||||||
|
@ -64,6 +64,69 @@
|
|||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#if defined(CONFIG_ARCH_USE_SEPARATED_SECTION) && !defined(CONFIG_ARCH_ADDRENV)
|
||||||
|
static int elf_section_alloc(FAR struct elf_loadinfo_s *loadinfo,
|
||||||
|
FAR Elf_Shdr *shdr, uint8_t idx)
|
||||||
|
{
|
||||||
|
if (loadinfo->ehdr.e_type != ET_REL)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loadinfo->sectalloc == NULL)
|
||||||
|
{
|
||||||
|
/* Allocate memory info for all sections */
|
||||||
|
|
||||||
|
loadinfo->sectalloc = kmm_zalloc(sizeof(uintptr_t) *
|
||||||
|
loadinfo->ehdr.e_shnum);
|
||||||
|
if (loadinfo->sectalloc == NULL)
|
||||||
|
{
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
elf_sectname(loadinfo, shdr);
|
||||||
|
if ((shdr->sh_flags & SHF_WRITE) != 0)
|
||||||
|
{
|
||||||
|
# ifdef CONFIG_ARCH_USE_DATA_HEAP
|
||||||
|
loadinfo->sectalloc[idx] = (uintptr_t)
|
||||||
|
up_dataheap_memalign(
|
||||||
|
(FAR const char *)loadinfo->iobuffer,
|
||||||
|
shdr->sh_addralign,
|
||||||
|
shdr->sh_size);
|
||||||
|
# else
|
||||||
|
loadinfo->sectalloc[idx] = (uintptr_t)kumm_memalign(shdr->sh_addralign,
|
||||||
|
shdr->sh_size);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
if (loadinfo->dataalloc == 0)
|
||||||
|
{
|
||||||
|
loadinfo->dataalloc = loadinfo->sectalloc[idx];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
# ifdef CONFIG_ARCH_USE_TEXT_HEAP
|
||||||
|
loadinfo->sectalloc[idx] = (uintptr_t)
|
||||||
|
up_textheap_memalign(
|
||||||
|
(FAR const char *)loadinfo->iobuffer,
|
||||||
|
shdr->sh_addralign,
|
||||||
|
shdr->sh_size);
|
||||||
|
# else
|
||||||
|
loadinfo->sectalloc[idx] = (uintptr_t)kumm_memalign(shdr->sh_addralign,
|
||||||
|
shdr->sh_size);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
if (loadinfo->textalloc == 0)
|
||||||
|
{
|
||||||
|
loadinfo->textalloc = loadinfo->sectalloc[idx];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: elf_elfsize
|
* Name: elf_elfsize
|
||||||
*
|
*
|
||||||
@ -104,6 +167,13 @@ static void elf_elfsize(FAR struct elf_loadinfo_s *loadinfo)
|
|||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
#if defined(CONFIG_ARCH_USE_SEPARATED_SECTION) && !defined(CONFIG_ARCH_ADDRENV)
|
||||||
|
if (elf_section_alloc(loadinfo, shdr, i) >= 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
datasize = _ALIGN_UP(datasize, shdr->sh_addralign);
|
datasize = _ALIGN_UP(datasize, shdr->sh_addralign);
|
||||||
datasize += ELF_ALIGNUP(shdr->sh_size);
|
datasize += ELF_ALIGNUP(shdr->sh_size);
|
||||||
if (loadinfo->dataalign < shdr->sh_addralign)
|
if (loadinfo->dataalign < shdr->sh_addralign)
|
||||||
@ -113,6 +183,13 @@ static void elf_elfsize(FAR struct elf_loadinfo_s *loadinfo)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
#if defined(CONFIG_ARCH_USE_SEPARATED_SECTION) && !defined(CONFIG_ARCH_ADDRENV)
|
||||||
|
if (elf_section_alloc(loadinfo, shdr, i) >= 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
textsize = _ALIGN_UP(textsize, shdr->sh_addralign);
|
textsize = _ALIGN_UP(textsize, shdr->sh_addralign);
|
||||||
textsize += ELF_ALIGNUP(shdr->sh_size);
|
textsize += ELF_ALIGNUP(shdr->sh_size);
|
||||||
if (loadinfo->textalign < shdr->sh_addralign)
|
if (loadinfo->textalign < shdr->sh_addralign)
|
||||||
@ -181,7 +258,7 @@ static inline int elf_loadfile(FAR struct elf_loadinfo_s *loadinfo)
|
|||||||
{
|
{
|
||||||
FAR uint8_t *text = (FAR uint8_t *)loadinfo->textalloc;
|
FAR uint8_t *text = (FAR uint8_t *)loadinfo->textalloc;
|
||||||
FAR uint8_t *data = (FAR uint8_t *)loadinfo->dataalloc;
|
FAR uint8_t *data = (FAR uint8_t *)loadinfo->dataalloc;
|
||||||
FAR uint8_t **pptr;
|
FAR uint8_t **pptr = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -193,6 +270,23 @@ static inline int elf_loadfile(FAR struct elf_loadinfo_s *loadinfo)
|
|||||||
{
|
{
|
||||||
FAR Elf_Shdr *shdr = &loadinfo->shdr[i];
|
FAR Elf_Shdr *shdr = &loadinfo->shdr[i];
|
||||||
|
|
||||||
|
/* SHF_ALLOC indicates that the section requires memory during
|
||||||
|
* execution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((shdr->sh_flags & SHF_ALLOC) == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARCH_USE_SEPARATED_SECTION
|
||||||
|
if (loadinfo->ehdr.e_type == ET_REL)
|
||||||
|
{
|
||||||
|
pptr = (FAR uint8_t **)&loadinfo->sectalloc[i];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
|
||||||
/* SHF_WRITE indicates that the section address space is write-
|
/* SHF_WRITE indicates that the section address space is write-
|
||||||
* able
|
* able
|
||||||
*/
|
*/
|
||||||
@ -262,7 +356,9 @@ static inline int elf_loadfile(FAR struct elf_loadinfo_s *loadinfo)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CONFIG_ARCH_USE_SEPARATED_SECTION
|
||||||
*pptr = (FAR uint8_t *)_ALIGN_UP((uintptr_t)*pptr, shdr->sh_addralign);
|
*pptr = (FAR uint8_t *)_ALIGN_UP((uintptr_t)*pptr, shdr->sh_addralign);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* SHT_NOBITS indicates that there is no data in the file for the
|
/* SHT_NOBITS indicates that there is no data in the file for the
|
||||||
* section.
|
* section.
|
||||||
@ -296,9 +392,16 @@ static inline int elf_loadfile(FAR struct elf_loadinfo_s *loadinfo)
|
|||||||
|
|
||||||
shdr->sh_addr = (uintptr_t)*pptr;
|
shdr->sh_addr = (uintptr_t)*pptr;
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARCH_USE_SEPARATED_SECTION
|
||||||
|
if (loadinfo->ehdr.e_type != ET_REL)
|
||||||
|
{
|
||||||
|
*pptr += ELF_ALIGNUP(shdr->sh_size);
|
||||||
|
}
|
||||||
|
#else
|
||||||
/* Setup the memory pointer for the next time through the loop */
|
/* Setup the memory pointer for the next time through the loop */
|
||||||
|
|
||||||
*pptr += ELF_ALIGNUP(shdr->sh_size);
|
*pptr += ELF_ALIGNUP(shdr->sh_size);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
|
@ -769,12 +769,17 @@ void up_extraheaps_init(void);
|
|||||||
* Name: up_textheap_memalign
|
* Name: up_textheap_memalign
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Allocate memory for text sections with the specified alignment.
|
* Allocate memory for text with the specified alignment and sectname.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#if defined(CONFIG_ARCH_USE_TEXT_HEAP)
|
#if defined(CONFIG_ARCH_USE_TEXT_HEAP)
|
||||||
|
# if defined(CONFIG_ARCH_USE_SEPARATED_SECTION)
|
||||||
|
FAR void *up_textheap_memalign(FAR const char *sectname,
|
||||||
|
size_t align, size_t size);
|
||||||
|
# else
|
||||||
FAR void *up_textheap_memalign(size_t align, size_t size);
|
FAR void *up_textheap_memalign(size_t align, size_t size);
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -849,12 +854,17 @@ void up_textheap_data_sync(void);
|
|||||||
* Name: up_dataheap_memalign
|
* Name: up_dataheap_memalign
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Allocate memory for data sections with the specified alignment.
|
* Allocate memory for data with the specified alignment and sectname.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#if defined(CONFIG_ARCH_USE_DATA_HEAP)
|
#if defined(CONFIG_ARCH_USE_DATA_HEAP)
|
||||||
|
# if defined(CONFIG_ARCH_USE_SEPARATED_SECTION)
|
||||||
|
FAR void *up_dataheap_memalign(FAR const char *sectname,
|
||||||
|
size_t align, size_t size);
|
||||||
|
# else
|
||||||
FAR void *up_dataheap_memalign(size_t align, size_t size);
|
FAR void *up_dataheap_memalign(size_t align, size_t size);
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -69,6 +69,10 @@ struct binary_s
|
|||||||
|
|
||||||
main_t entrypt; /* Entry point into a program module */
|
main_t entrypt; /* Entry point into a program module */
|
||||||
FAR void *mapped; /* Memory-mapped, address space */
|
FAR void *mapped; /* Memory-mapped, address space */
|
||||||
|
#ifdef CONFIG_ARCH_USE_SEPARATED_SECTION
|
||||||
|
FAR void **sectalloc; /* All sections memory allocated */
|
||||||
|
uint16_t nsect; /* Number of sections */
|
||||||
|
#endif
|
||||||
FAR void *alloc[BINFMT_NALLOC]; /* Allocated address spaces */
|
FAR void *alloc[BINFMT_NALLOC]; /* Allocated address spaces */
|
||||||
|
|
||||||
#ifdef CONFIG_BINFMT_CONSTRUCTORS
|
#ifdef CONFIG_BINFMT_CONSTRUCTORS
|
||||||
|
@ -79,6 +79,10 @@ struct elf_loadinfo_s
|
|||||||
* after the ELF module has been loaded.
|
* after the ELF module has been loaded.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARCH_USE_SEPARATED_SECTION
|
||||||
|
FAR uintptr_t *sectalloc; /* All sections memory allocated when ELF file was loaded */
|
||||||
|
#endif
|
||||||
|
|
||||||
uintptr_t textalloc; /* .text memory allocated when ELF file was loaded */
|
uintptr_t textalloc; /* .text memory allocated when ELF file was loaded */
|
||||||
uintptr_t dataalloc; /* .bss/.data memory allocated when ELF file was loaded */
|
uintptr_t dataalloc; /* .bss/.data memory allocated when ELF file was loaded */
|
||||||
size_t textsize; /* Size of the ELF .text memory allocation */
|
size_t textsize; /* Size of the ELF .text memory allocation */
|
||||||
|
@ -191,6 +191,10 @@ struct mod_loadinfo_s
|
|||||||
* after the module has been loaded.
|
* after the module has been loaded.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARCH_USE_SEPARATED_SECTION
|
||||||
|
uintptr_t *sectalloc; /* All sections memory allocated when ELF file was loaded */
|
||||||
|
#endif
|
||||||
|
|
||||||
uintptr_t textalloc; /* .text memory allocated when module was loaded */
|
uintptr_t textalloc; /* .text memory allocated when module was loaded */
|
||||||
uintptr_t datastart; /* Start of.bss/.data memory in .text allocation */
|
uintptr_t datastart; /* Start of.bss/.data memory in .text allocation */
|
||||||
size_t textsize; /* Size of the module .text memory allocation */
|
size_t textsize; /* Size of the module .text memory allocation */
|
||||||
|
@ -89,6 +89,14 @@ static void dldump_loadinfo(FAR struct mod_loadinfo_s *loadinfo)
|
|||||||
{
|
{
|
||||||
FAR Elf_Shdr *shdr = &loadinfo->shdr[i];
|
FAR Elf_Shdr *shdr = &loadinfo->shdr[i];
|
||||||
binfo("Sections %d:\n", i);
|
binfo("Sections %d:\n", 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(" sh_name: %08x\n", shdr->sh_name);
|
binfo(" sh_name: %08x\n", shdr->sh_name);
|
||||||
binfo(" sh_type: %08x\n", shdr->sh_type);
|
binfo(" sh_type: %08x\n", shdr->sh_type);
|
||||||
binfo(" sh_flags: %08x\n", shdr->sh_flags);
|
binfo(" sh_flags: %08x\n", shdr->sh_flags);
|
||||||
|
@ -961,8 +961,28 @@ int modlib_bind(FAR struct module_s *modp,
|
|||||||
* contents to memory and invalidating the I cache).
|
* contents to memory and invalidating the I cache).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
up_coherent_dcache(loadinfo->textalloc, loadinfo->textsize);
|
if (loadinfo->textsize > 0)
|
||||||
up_coherent_dcache(loadinfo->datastart, loadinfo->datasize);
|
{
|
||||||
|
up_coherent_dcache(loadinfo->textalloc, loadinfo->textsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loadinfo->datasize > 0)
|
||||||
|
{
|
||||||
|
up_coherent_dcache(loadinfo->datastart, 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
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,69 @@
|
|||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARCH_USE_SEPARATED_SECTION
|
||||||
|
static int modlib_section_alloc(FAR struct mod_loadinfo_s *loadinfo,
|
||||||
|
FAR Elf_Shdr *shdr, uint8_t idx)
|
||||||
|
{
|
||||||
|
if (loadinfo->ehdr.e_type != ET_REL)
|
||||||
|
{
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loadinfo->sectalloc == NULL)
|
||||||
|
{
|
||||||
|
/* Allocate memory info for all sections */
|
||||||
|
|
||||||
|
loadinfo->sectalloc = lib_zalloc(sizeof(uintptr_t) *
|
||||||
|
loadinfo->ehdr.e_shnum);
|
||||||
|
if (loadinfo->sectalloc == NULL)
|
||||||
|
{
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
modlib_sectname(loadinfo, shdr);
|
||||||
|
if ((shdr->sh_flags & SHF_WRITE) != 0)
|
||||||
|
{
|
||||||
|
# ifdef CONFIG_ARCH_USE_DATA_HEAP
|
||||||
|
loadinfo->sectalloc[idx] = (uintptr_t)
|
||||||
|
up_dataheap_memalign(
|
||||||
|
(FAR const char *)loadinfo->iobuffer,
|
||||||
|
shdr->sh_addralign,
|
||||||
|
shdr->sh_size);
|
||||||
|
# else
|
||||||
|
loadinfo->sectalloc[idx] = (uintptr_t)lib_memalign(shdr->sh_addralign,
|
||||||
|
shdr->sh_size);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
if (loadinfo->datastart == 0)
|
||||||
|
{
|
||||||
|
loadinfo->datastart = loadinfo->sectalloc[idx];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
# ifdef CONFIG_ARCH_USE_TEXT_HEAP
|
||||||
|
loadinfo->sectalloc[idx] = (uintptr_t)
|
||||||
|
up_textheap_memalign(
|
||||||
|
(FAR const char *)loadinfo->iobuffer,
|
||||||
|
shdr->sh_addralign,
|
||||||
|
shdr->sh_size);
|
||||||
|
# else
|
||||||
|
loadinfo->sectalloc[idx] = (uintptr_t)lib_memalign(shdr->sh_addralign,
|
||||||
|
shdr->sh_size);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
if (loadinfo->textalloc == 0)
|
||||||
|
{
|
||||||
|
loadinfo->textalloc = loadinfo->sectalloc[idx];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: modlib_elfsize
|
* Name: modlib_elfsize
|
||||||
*
|
*
|
||||||
@ -70,7 +133,10 @@ static void modlib_elfsize(FAR struct mod_loadinfo_s *loadinfo)
|
|||||||
size_t datasize = 0;
|
size_t datasize = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Accumulate the size each section into memory that is marked SHF_ALLOC */
|
/* Accumulate the size each section into memory that is marked SHF_ALLOC
|
||||||
|
* if CONFIG_ARCH_USE_SEPARATED_SECTION is enabled, allocate
|
||||||
|
* (and zero) memory for the each section.
|
||||||
|
*/
|
||||||
|
|
||||||
if (loadinfo->ehdr.e_phnum > 0)
|
if (loadinfo->ehdr.e_phnum > 0)
|
||||||
{
|
{
|
||||||
@ -118,6 +184,13 @@ static void modlib_elfsize(FAR struct mod_loadinfo_s *loadinfo)
|
|||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_ARCH_USE_SEPARATED_SECTION
|
||||||
|
if (modlib_section_alloc(loadinfo, shdr, i) >= 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
datasize = _ALIGN_UP(datasize, shdr->sh_addralign);
|
datasize = _ALIGN_UP(datasize, shdr->sh_addralign);
|
||||||
datasize += ELF_ALIGNUP(shdr->sh_size);
|
datasize += ELF_ALIGNUP(shdr->sh_size);
|
||||||
if (loadinfo->dataalign < shdr->sh_addralign)
|
if (loadinfo->dataalign < shdr->sh_addralign)
|
||||||
@ -127,6 +200,13 @@ static void modlib_elfsize(FAR struct mod_loadinfo_s *loadinfo)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_ARCH_USE_SEPARATED_SECTION
|
||||||
|
if (modlib_section_alloc(loadinfo, shdr, i) >= 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
textsize = _ALIGN_UP(textsize, shdr->sh_addralign);
|
textsize = _ALIGN_UP(textsize, shdr->sh_addralign);
|
||||||
textsize += ELF_ALIGNUP(shdr->sh_size);
|
textsize += ELF_ALIGNUP(shdr->sh_size);
|
||||||
if (loadinfo->textalign < shdr->sh_addralign)
|
if (loadinfo->textalign < shdr->sh_addralign)
|
||||||
@ -161,7 +241,6 @@ static inline int modlib_loadfile(FAR struct mod_loadinfo_s *loadinfo)
|
|||||||
{
|
{
|
||||||
FAR uint8_t *text = (FAR uint8_t *)loadinfo->textalloc;
|
FAR uint8_t *text = (FAR uint8_t *)loadinfo->textalloc;
|
||||||
FAR uint8_t *data = (FAR uint8_t *)loadinfo->datastart;
|
FAR uint8_t *data = (FAR uint8_t *)loadinfo->datastart;
|
||||||
FAR uint8_t **pptr;
|
|
||||||
int ret;
|
int ret;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -204,6 +283,7 @@ static inline int modlib_loadfile(FAR struct mod_loadinfo_s *loadinfo)
|
|||||||
for (i = 0; i < loadinfo->ehdr.e_shnum; i++)
|
for (i = 0; i < loadinfo->ehdr.e_shnum; i++)
|
||||||
{
|
{
|
||||||
FAR Elf_Shdr *shdr = &loadinfo->shdr[i];
|
FAR Elf_Shdr *shdr = &loadinfo->shdr[i];
|
||||||
|
FAR uint8_t **pptr = NULL;
|
||||||
|
|
||||||
/* SHF_ALLOC indicates that the section requires memory during
|
/* SHF_ALLOC indicates that the section requires memory during
|
||||||
* execution
|
* execution
|
||||||
@ -214,25 +294,35 @@ static inline int modlib_loadfile(FAR struct mod_loadinfo_s *loadinfo)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SHF_WRITE indicates that the section address space is write-
|
#ifdef CONFIG_ARCH_USE_SEPARATED_SECTION
|
||||||
* able
|
if (loadinfo->ehdr.e_type == ET_REL)
|
||||||
*/
|
{
|
||||||
|
pptr = (FAR uint8_t **)&loadinfo->sectalloc[i];
|
||||||
if ((shdr->sh_flags & SHF_WRITE) != 0
|
}
|
||||||
#ifdef CONFIG_ARCH_HAVE_TEXT_HEAP_WORD_ALIGNED_READ
|
|
||||||
|| (shdr->sh_flags & SHF_EXECINSTR) == 0
|
|
||||||
#endif
|
#endif
|
||||||
)
|
|
||||||
{
|
|
||||||
pptr = &data;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pptr = &text;
|
|
||||||
}
|
|
||||||
|
|
||||||
*pptr = (FAR uint8_t *)_ALIGN_UP((uintptr_t)*pptr,
|
if (pptr == NULL)
|
||||||
shdr->sh_addralign);
|
{
|
||||||
|
/* SHF_WRITE indicates that the section address space is
|
||||||
|
* writeable
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((shdr->sh_flags & SHF_WRITE) != 0
|
||||||
|
#ifdef CONFIG_ARCH_HAVE_TEXT_HEAP_WORD_ALIGNED_READ
|
||||||
|
|| (shdr->sh_flags & SHF_EXECINSTR) == 0
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
{
|
||||||
|
pptr = &data;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pptr = &text;
|
||||||
|
}
|
||||||
|
|
||||||
|
*pptr = (FAR uint8_t *)_ALIGN_UP((uintptr_t)*pptr,
|
||||||
|
shdr->sh_addralign);
|
||||||
|
}
|
||||||
|
|
||||||
/* SHT_NOBITS indicates that there is no data in the file for the
|
/* SHT_NOBITS indicates that there is no data in the file for the
|
||||||
* section.
|
* section.
|
||||||
@ -267,9 +357,16 @@ static inline int modlib_loadfile(FAR struct mod_loadinfo_s *loadinfo)
|
|||||||
|
|
||||||
shdr->sh_addr = (uintptr_t)*pptr;
|
shdr->sh_addr = (uintptr_t)*pptr;
|
||||||
|
|
||||||
|
#ifdef CONFIG_ARCH_USE_SEPARATED_SECTION
|
||||||
|
if (loadinfo->ehdr.e_type != ET_REL)
|
||||||
|
{
|
||||||
|
*pptr += ELF_ALIGNUP(shdr->sh_size);
|
||||||
|
}
|
||||||
|
#else
|
||||||
/* Setup the memory pointer for the next time through the loop */
|
/* Setup the memory pointer for the next time through the loop */
|
||||||
|
|
||||||
*pptr += ELF_ALIGNUP(shdr->sh_size);
|
*pptr += ELF_ALIGNUP(shdr->sh_size);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -324,18 +421,19 @@ int modlib_load(FAR struct mod_loadinfo_s *loadinfo)
|
|||||||
|
|
||||||
if (loadinfo->ehdr.e_type == ET_REL)
|
if (loadinfo->ehdr.e_type == ET_REL)
|
||||||
{
|
{
|
||||||
|
#ifndef CONFIG_ARCH_USE_SEPARATED_SECTION
|
||||||
if (loadinfo->textsize > 0)
|
if (loadinfo->textsize > 0)
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_ARCH_USE_TEXT_HEAP)
|
# ifdef CONFIG_ARCH_USE_TEXT_HEAP
|
||||||
loadinfo->textalloc = (uintptr_t)
|
loadinfo->textalloc = (uintptr_t)
|
||||||
up_textheap_memalign(loadinfo->textalign,
|
up_textheap_memalign(loadinfo->textalign,
|
||||||
loadinfo->textsize +
|
loadinfo->textsize +
|
||||||
loadinfo->segpad);
|
loadinfo->segpad);
|
||||||
#else
|
# else
|
||||||
loadinfo->textalloc = (uintptr_t)lib_memalign(loadinfo->textalign,
|
loadinfo->textalloc = (uintptr_t)lib_memalign(loadinfo->textalign,
|
||||||
loadinfo->textsize +
|
loadinfo->textsize +
|
||||||
loadinfo->segpad);
|
loadinfo->segpad);
|
||||||
#endif
|
# endif
|
||||||
if (!loadinfo->textalloc)
|
if (!loadinfo->textalloc)
|
||||||
{
|
{
|
||||||
berr("ERROR: Failed to allocate memory for the module text\n");
|
berr("ERROR: Failed to allocate memory for the module text\n");
|
||||||
@ -346,14 +444,14 @@ int modlib_load(FAR struct mod_loadinfo_s *loadinfo)
|
|||||||
|
|
||||||
if (loadinfo->datasize > 0)
|
if (loadinfo->datasize > 0)
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_ARCH_USE_DATA_HEAP)
|
# ifdef CONFIG_ARCH_USE_DATA_HEAP
|
||||||
loadinfo->datastart = (uintptr_t)
|
loadinfo->datastart = (uintptr_t)
|
||||||
up_dataheap_memalign(loadinfo->dataalign,
|
up_dataheap_memalign(loadinfo->dataalign,
|
||||||
loadinfo->datasize);
|
loadinfo->datasize);
|
||||||
#else
|
# else
|
||||||
loadinfo->datastart = (uintptr_t)lib_memalign(loadinfo->dataalign,
|
loadinfo->datastart = (uintptr_t)lib_memalign(loadinfo->dataalign,
|
||||||
loadinfo->datasize);
|
loadinfo->datasize);
|
||||||
#endif
|
# endif
|
||||||
if (!loadinfo->datastart)
|
if (!loadinfo->datastart)
|
||||||
{
|
{
|
||||||
berr("ERROR: Failed to allocate memory for the module data\n");
|
berr("ERROR: Failed to allocate memory for the module data\n");
|
||||||
@ -361,6 +459,7 @@ int modlib_load(FAR struct mod_loadinfo_s *loadinfo)
|
|||||||
goto errout_with_buffers;
|
goto errout_with_buffers;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -62,6 +62,33 @@ int modlib_unload(FAR struct mod_loadinfo_s *loadinfo)
|
|||||||
|
|
||||||
if (loadinfo->ehdr.e_type != ET_DYN)
|
if (loadinfo->ehdr.e_type != ET_DYN)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_ARCH_USE_SEPARATED_SECTION
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; loadinfo->sectalloc[i] != 0 &&
|
||||||
|
i < loadinfo->ehdr.e_shnum; i++)
|
||||||
|
{
|
||||||
|
# ifdef CONFIG_ARCH_USE_TEXT_HEAP
|
||||||
|
if (up_textheap_heapmember((FAR void *)loadinfo->sectalloc[i]))
|
||||||
|
{
|
||||||
|
up_textheap_free((FAR void *)loadinfo->sectalloc[i]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# ifdef CONFIG_ARCH_USE_DATA_HEAP
|
||||||
|
if (up_dataheap_heapmember((FAR void *)loadinfo->sectalloc[i]))
|
||||||
|
{
|
||||||
|
up_dataheap_free((FAR void *)loadinfo->sectalloc[i]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
lib_free((FAR void *)loadinfo->sectalloc[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
lib_free(loadinfo->sectalloc);
|
||||||
|
#else
|
||||||
if (loadinfo->textalloc != 0)
|
if (loadinfo->textalloc != 0)
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_ARCH_USE_TEXT_HEAP)
|
#if defined(CONFIG_ARCH_USE_TEXT_HEAP)
|
||||||
@ -79,6 +106,7 @@ int modlib_unload(FAR struct mod_loadinfo_s *loadinfo)
|
|||||||
lib_free((FAR void *)loadinfo->datastart);
|
lib_free((FAR void *)loadinfo->datastart);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -90,6 +90,14 @@ static void mod_dumploadinfo(FAR struct mod_loadinfo_s *loadinfo)
|
|||||||
{
|
{
|
||||||
FAR Elf_Shdr *shdr = &loadinfo->shdr[i];
|
FAR Elf_Shdr *shdr = &loadinfo->shdr[i];
|
||||||
binfo("Sections %d:\n", i);
|
binfo("Sections %d:\n", 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(" sh_name: %08x\n", shdr->sh_name);
|
binfo(" sh_name: %08x\n", shdr->sh_name);
|
||||||
binfo(" sh_type: %08x\n", shdr->sh_type);
|
binfo(" sh_type: %08x\n", shdr->sh_type);
|
||||||
binfo(" sh_flags: %08jx\n", (uintmax_t)shdr->sh_flags);
|
binfo(" sh_flags: %08jx\n", (uintmax_t)shdr->sh_flags);
|
||||||
|
Loading…
Reference in New Issue
Block a user