modlib:if elf in romfs/tmpfs, try use xipbase
Signed-off-by: anjiahao <anjiahao@xiaomi.com>
This commit is contained in:
parent
112b6fd9a5
commit
a72e9e5621
|
@ -160,6 +160,10 @@ struct module_s
|
|||
struct mod_info_s modinfo; /* Module information */
|
||||
FAR void *textalloc; /* Allocated kernel text memory */
|
||||
FAR void *dataalloc; /* Allocated kernel memory */
|
||||
uintptr_t xipbase; /* if elf is position independent, and use
|
||||
* romfs/tmps, we can try get xipbase,
|
||||
* skip the copy.
|
||||
*/
|
||||
#ifdef CONFIG_ARCH_USE_SEPARATED_SECTION
|
||||
FAR void **sectalloc; /* All sections memory allocated when ELF file was loaded */
|
||||
uint16_t nsect; /* Number of entries in sectalloc array */
|
||||
|
@ -232,6 +236,10 @@ struct mod_loadinfo_s
|
|||
int filfd; /* Descriptor for the file being loaded */
|
||||
int nexports; /* ET_DYN - Number of symbols exported */
|
||||
int gotindex; /* Index to the GOT section */
|
||||
uintptr_t xipbase; /* if elf is position independent, and use
|
||||
* romfs/tmps, we can try get xipbase,
|
||||
* skip the copy.
|
||||
*/
|
||||
|
||||
/* Address environment.
|
||||
*
|
||||
|
|
|
@ -1045,6 +1045,8 @@ int modlib_bind(FAR struct module_s *modp,
|
|||
}
|
||||
}
|
||||
|
||||
modp->xipbase = loadinfo->xipbase;
|
||||
|
||||
/* Ensure that the I and D caches are coherent before starting the newly
|
||||
* loaded module by cleaning the D cache (i.e., flushing the D cache
|
||||
* contents to memory and invalidating the I cache).
|
||||
|
|
|
@ -32,12 +32,14 @@
|
|||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/lib/modlib.h>
|
||||
#include <nuttx/fs/ioctl.h>
|
||||
|
||||
#include "libc.h"
|
||||
#include "modlib/modlib.h"
|
||||
|
@ -62,7 +64,7 @@
|
|||
static int modlib_section_alloc(FAR struct mod_loadinfo_s *loadinfo,
|
||||
FAR Elf_Shdr *shdr, uint8_t idx)
|
||||
{
|
||||
if (loadinfo->ehdr.e_type != ET_DYN)
|
||||
if (loadinfo->ehdr.e_type == ET_DYN)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -98,6 +100,14 @@ static int modlib_section_alloc(FAR struct mod_loadinfo_s *loadinfo,
|
|||
loadinfo->datastart = loadinfo->sectalloc[idx];
|
||||
}
|
||||
}
|
||||
else if (loadinfo->xipbase != 0)
|
||||
{
|
||||
loadinfo->sectalloc[idx] = loadinfo->xipbase + shdr->sh_offset;
|
||||
if (loadinfo->textalloc == 0)
|
||||
{
|
||||
loadinfo->textalloc = loadinfo->sectalloc[idx];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
# ifdef CONFIG_ARCH_USE_TEXT_HEAP
|
||||
|
@ -107,8 +117,9 @@ static int modlib_section_alloc(FAR struct mod_loadinfo_s *loadinfo,
|
|||
shdr->sh_addralign,
|
||||
shdr->sh_size);
|
||||
# else
|
||||
loadinfo->sectalloc[idx] = (uintptr_t)lib_memalign(shdr->sh_addralign,
|
||||
shdr->sh_size);
|
||||
loadinfo->sectalloc[idx] = (uintptr_t)
|
||||
lib_memalign(shdr->sh_addralign,
|
||||
shdr->sh_size);
|
||||
# endif
|
||||
|
||||
if (loadinfo->textalloc == 0)
|
||||
|
@ -365,8 +376,20 @@ static inline int modlib_loadfile(FAR struct mod_loadinfo_s *loadinfo)
|
|||
pptr = &text;
|
||||
}
|
||||
|
||||
*pptr = (FAR uint8_t *)_ALIGN_UP((uintptr_t)*pptr,
|
||||
shdr->sh_addralign);
|
||||
if (loadinfo->xipbase == 0)
|
||||
{
|
||||
/* If xipbase is not set, align the address
|
||||
* xipbase is set, the address can't be aligned
|
||||
*/
|
||||
|
||||
*pptr = (FAR uint8_t *)_ALIGN_UP((uintptr_t)*pptr,
|
||||
shdr->sh_addralign);
|
||||
}
|
||||
}
|
||||
|
||||
if ((shdr->sh_flags & SHF_WRITE) == 0 && loadinfo->xipbase != 0)
|
||||
{
|
||||
goto skipload;
|
||||
}
|
||||
|
||||
/* SHT_NOBITS indicates that there is no data in the file for the
|
||||
|
@ -406,6 +429,8 @@ static inline int modlib_loadfile(FAR struct mod_loadinfo_s *loadinfo)
|
|||
}
|
||||
#endif
|
||||
|
||||
skipload:
|
||||
|
||||
/* Update sh_addr to point to copy in memory */
|
||||
|
||||
binfo("%d. %08lx->%08lx\n", i,
|
||||
|
@ -497,6 +522,11 @@ int modlib_load(FAR struct mod_loadinfo_s *loadinfo)
|
|||
if (loadinfo->gotindex >= 0)
|
||||
{
|
||||
binfo("GOT section found! index %d\n", loadinfo->gotindex);
|
||||
if (ioctl(loadinfo->filfd, FIOC_XIPBASE,
|
||||
(unsigned long)&loadinfo->xipbase) >= 0)
|
||||
{
|
||||
binfo("can use xipbase %zu\n", loadinfo->xipbase);
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine total size to allocate */
|
||||
|
@ -517,7 +547,12 @@ int modlib_load(FAR struct mod_loadinfo_s *loadinfo)
|
|||
if (loadinfo->ehdr.e_type == ET_REL || loadinfo->ehdr.e_type == ET_EXEC)
|
||||
{
|
||||
# ifndef CONFIG_ARCH_USE_SEPARATED_SECTION
|
||||
if (loadinfo->textsize > 0)
|
||||
if (loadinfo->xipbase != 0)
|
||||
{
|
||||
loadinfo->textalloc = loadinfo->xipbase +
|
||||
loadinfo->shdr[1].sh_offset;
|
||||
}
|
||||
else if (loadinfo->textsize > 0)
|
||||
{
|
||||
# ifdef CONFIG_ARCH_USE_TEXT_HEAP
|
||||
loadinfo->textalloc = (uintptr_t)
|
||||
|
@ -643,6 +678,11 @@ int modlib_load_with_addrenv(FAR struct mod_loadinfo_s *loadinfo)
|
|||
if (loadinfo->gotindex >= 0)
|
||||
{
|
||||
binfo("GOT section found! index %d\n", loadinfo->gotindex);
|
||||
if (ioctl(loadinfo->filfd, FIOC_XIPBASE,
|
||||
(unsigned long)&loadinfo->xipbase) >= 0)
|
||||
{
|
||||
binfo("can use xipbase %zu\n", loadinfo->xipbase);
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine total size to allocate */
|
||||
|
|
|
@ -132,11 +132,15 @@ int modlib_uninit(FAR struct module_s *modp)
|
|||
modp->sectalloc = NULL;
|
||||
modp->nsect = 0;
|
||||
#else
|
||||
if (modp->xipbase == 0)
|
||||
{
|
||||
# if defined(CONFIG_ARCH_USE_TEXT_HEAP)
|
||||
up_textheap_free((FAR void *)modp->textalloc);
|
||||
up_textheap_free((FAR void *)modp->textalloc);
|
||||
# else
|
||||
lib_free((FAR void *)modp->textalloc);
|
||||
lib_free((FAR void *)modp->textalloc);
|
||||
# endif
|
||||
}
|
||||
|
||||
# if defined(CONFIG_ARCH_USE_DATA_HEAP)
|
||||
up_dataheap_free((FAR void *)modp->dataalloc);
|
||||
# else
|
||||
|
|
|
@ -99,7 +99,7 @@ int modlib_unload(FAR struct mod_loadinfo_s *loadinfo)
|
|||
|
||||
lib_free(loadinfo->sectalloc);
|
||||
#else
|
||||
if (loadinfo->textalloc != 0)
|
||||
if (loadinfo->textalloc != 0 && loadinfo->xipbase == 0)
|
||||
{
|
||||
# if defined(CONFIG_ARCH_USE_TEXT_HEAP)
|
||||
up_textheap_free((FAR void *)loadinfo->textalloc);
|
||||
|
|
Loading…
Reference in New Issue