binfmt: Support arch copy section by self for dynamic code loading

This option enables architecture-specific memory copy for dynamic code loading.

For example, Ambiq has MRAM regions for instruction which can't load by
the memcpy directly.

Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
This commit is contained in:
wangjianyu3 2023-08-23 01:11:24 +08:00 committed by Xiang Xiao
parent c749e4bfbd
commit 8a13da322d
3 changed files with 73 additions and 7 deletions

View File

@ -401,6 +401,12 @@ config ARCH_HAVE_TEXT_HEAP
---help---
Special memory region for dynamic code loading
config ARCH_HAVE_COPY_SECTION
bool
default n
---help---
Section copying for dynamic code loading
config ARCH_HAVE_MULTICPU
bool
default n
@ -623,6 +629,15 @@ menuconfig ARCH_ADDRENV
Support per-task address environments using the MMU... i.e., support
"processes"
config ARCH_USE_COPY_SECTION
bool "Enable arch copy section by self for dynamic code loading"
default n
depends on ARCH_HAVE_COPY_SECTION
---help---
This option enables architecture-specific memory copy for
dynamic code loading. For example, Ambiq has MRAM regions
for instruction which can't load by the memcpy directly.
if ARCH_ADDRENV && ARCH_NEED_ADDRENV_MAPPING
config ARCH_TEXT_VBASE

View File

@ -98,9 +98,23 @@ static inline void elf_dumpreaddata(FAR char *buffer, size_t buflen)
int elf_read(FAR struct elf_loadinfo_s *loadinfo, FAR uint8_t *buffer,
size_t readsize, off_t offset)
{
size_t nsize = readsize;
ssize_t nbytes; /* Number of bytes read */
off_t rpos; /* Position returned by lseek */
size_t nsize = readsize; /* Bytes to read from the object file */
ssize_t nbytes; /* Number of bytes read */
off_t rpos; /* Position returned by lseek */
int ret = OK; /* Return value */
#ifdef CONFIG_ARCH_USE_COPY_SECTION
FAR uint8_t *dest = buffer; /* Destination address - `buffer` */
/* Redirect `buffer` to temporary allocated memory */
buffer = kmm_malloc(readsize);
if (buffer == NULL)
{
berr("ERROR: Failed to allocate memory\n");
return -ENOMEM;
}
#endif
binfo("Read %zu bytes from offset %" PRIdOFF "\n", readsize, offset);
@ -115,7 +129,8 @@ int elf_read(FAR struct elf_loadinfo_s *loadinfo, FAR uint8_t *buffer,
{
berr("Failed to seek to position %" PRIdOFF ": %" PRIdOFF "\n",
offset, rpos);
return rpos;
ret = rpos;
goto errout;
}
/* Read the file data at offset into the user buffer */
@ -130,13 +145,15 @@ int elf_read(FAR struct elf_loadinfo_s *loadinfo, FAR uint8_t *buffer,
{
berr("Read from offset %" PRIdOFF " failed: %zd\n",
offset, nbytes);
return nbytes;
ret = nbytes;
goto errout;
}
}
else if (nbytes == 0)
{
berr("Unexpected end of file\n");
return -ENODATA;
ret = -ENODATA;
goto errout;
}
else
{
@ -145,6 +162,25 @@ int elf_read(FAR struct elf_loadinfo_s *loadinfo, FAR uint8_t *buffer,
}
}
#ifdef CONFIG_ARCH_USE_COPY_SECTION
/* Copy the requested data from temporary memory to destination */
ret = up_copy_section(dest, buffer, nsize);
if (ret < 0)
{
berr("ERROR: Failed to copy section at offset %"PRIdOFF"\n", offset);
goto errout;
}
#endif
elf_dumpreaddata(buffer, nsize);
return OK;
errout:
#ifdef CONFIG_ARCH_USE_COPY_SECTION
/* Free the temporary memory */
kmm_free(buffer);
#endif
return ret;
}

View File

@ -772,6 +772,21 @@ void up_textheap_free(FAR void *p);
bool up_textheap_heapmember(FAR void *p);
#endif
/****************************************************************************
* Name: up_copy_section
*
* Description:
* Copy section from general temporary buffer(src) to special addr(dest).
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
****************************************************************************/
#if defined(CONFIG_ARCH_USE_COPY_SECTION)
int up_copy_section(FAR void *dest, FAR const void *src, size_t n);
#endif
/****************************************************************************
* Name: up_setpicbase and up_getpicbase
*