mirror of
https://github.com/apache/nuttx.git
synced 2026-08-01 20:28:58 +00:00
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
6e746ed364
commit
1f1d90de1c
18 changed files with 507 additions and 48 deletions
|
|
@ -161,6 +161,32 @@ 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]);
|
||||
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 */
|
||||
|
||||
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]);
|
||||
}
|
||||
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]);
|
||||
|
|
|
|||
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++)
|
||||
{
|
||||
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);
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -146,13 +146,15 @@ errout_with_addrenv:
|
|||
|
||||
/* 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)
|
||||
{
|
||||
|
|
@ -161,19 +163,20 @@ errout_with_addrenv:
|
|||
|
||||
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
|
||||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -64,6 +64,69 @@
|
|||
* 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
|
||||
*
|
||||
|
|
@ -104,6 +167,13 @@ static void elf_elfsize(FAR struct elf_loadinfo_s *loadinfo)
|
|||
#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 += ELF_ALIGNUP(shdr->sh_size);
|
||||
if (loadinfo->dataalign < shdr->sh_addralign)
|
||||
|
|
@ -113,6 +183,13 @@ static void elf_elfsize(FAR struct elf_loadinfo_s *loadinfo)
|
|||
}
|
||||
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 += ELF_ALIGNUP(shdr->sh_size);
|
||||
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 *data = (FAR uint8_t *)loadinfo->dataalloc;
|
||||
FAR uint8_t **pptr;
|
||||
FAR uint8_t **pptr = NULL;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
|
|
@ -193,6 +270,23 @@ static inline int elf_loadfile(FAR struct elf_loadinfo_s *loadinfo)
|
|||
{
|
||||
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-
|
||||
* able
|
||||
*/
|
||||
|
|
@ -262,7 +356,9 @@ static inline int elf_loadfile(FAR struct elf_loadinfo_s *loadinfo)
|
|||
continue;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_ARCH_USE_SEPARATED_SECTION
|
||||
*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
|
||||
* section.
|
||||
|
|
@ -296,9 +392,16 @@ static inline int elf_loadfile(FAR struct elf_loadinfo_s *loadinfo)
|
|||
|
||||
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 */
|
||||
|
||||
*pptr += ELF_ALIGNUP(shdr->sh_size);
|
||||
#endif
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue