mirror of
https://github.com/apache/nuttx.git
synced 2025-01-13 10:58:49 +08:00
Change when address environment is instantiated; there are/were locations where access is made to the allocation address environment when it is not yet in place
This commit is contained in:
parent
dbeba82e85
commit
d52599fe8e
2 changed files with 80 additions and 73 deletions
|
@ -195,42 +195,14 @@ static int elf_relocate(FAR struct elf_loadinfo_s *loadinfo, int relidx,
|
|||
|
||||
addr = dstsec->sh_addr + rel.r_offset;
|
||||
|
||||
/* If CONFIG_ARCH_ADDRENV=y, then 'addr' lies in a virtual address space that
|
||||
* may not be in place now. elf_addrenv_select() will temporarily
|
||||
* instantiate that address space.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
ret = elf_addrenv_select(loadinfo);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("ERROR: elf_addrenv_select() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Now perform the architecture-specific relocation */
|
||||
|
||||
ret = up_relocate(&rel, &sym, addr);
|
||||
if (ret < 0)
|
||||
{
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
(void)elf_addrenv_restore(loadinfo);
|
||||
#endif
|
||||
bdbg("ERROR: Section %d reloc %d: Relocation failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Restore the original address environment */
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
ret = elf_addrenv_restore(loadinfo);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("ERROR: elf_addrenv_restore() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
@ -263,6 +235,9 @@ static int elf_relocateadd(FAR struct elf_loadinfo_s *loadinfo, int relidx,
|
|||
int elf_bind(FAR struct elf_loadinfo_s *loadinfo,
|
||||
FAR const struct symtab_s *exports, int nexports)
|
||||
{
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
int status;
|
||||
#endif
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
|
@ -285,6 +260,20 @@ int elf_bind(FAR struct elf_loadinfo_s *loadinfo,
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
/* If CONFIG_ARCH_ADDRENV=y, then the loaded ELF lies in a virtual address
|
||||
* space that may not be in place now. elf_addrenv_select() will
|
||||
* temporarily instantiate that address space.
|
||||
*/
|
||||
|
||||
ret = elf_addrenv_select(loadinfo);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("ERROR: elf_addrenv_select() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Process relocations in every allocated section */
|
||||
|
||||
for (i = 1; i < loadinfo->ehdr.e_shnum; i++)
|
||||
|
@ -332,5 +321,19 @@ int elf_bind(FAR struct elf_loadinfo_s *loadinfo,
|
|||
up_coherent_dcache(loadinfo->textalloc, loadinfo->textsize);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
/* Restore the original address environment */
|
||||
|
||||
status = elf_addrenv_restore(loadinfo);
|
||||
if (status < 0)
|
||||
{
|
||||
bdbg("ERROR: elf_addrenv_restore() failed: %d\n", status);
|
||||
if (ret == OK)
|
||||
{
|
||||
ret = status;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -132,9 +132,8 @@ static void elf_elfsize(struct elf_loadinfo_s *loadinfo)
|
|||
* Name: elf_loadfile
|
||||
*
|
||||
* Description:
|
||||
* Allocate memory for the file and read the section data into the
|
||||
* allocated memory. Section addresses in the shdr[] are updated to point
|
||||
* to the corresponding position in the allocated memory.
|
||||
* Read the section data into memory. Section addresses in the shdr[] are
|
||||
* updated to point to the corresponding position in the memory.
|
||||
*
|
||||
* Returned Value:
|
||||
* 0 (OK) is returned on success and a negated errno is returned on
|
||||
|
@ -150,15 +149,6 @@ static inline int elf_loadfile(FAR struct elf_loadinfo_s *loadinfo)
|
|||
int ret;
|
||||
int i;
|
||||
|
||||
/* Allocate (and zero) memory for the ELF file. */
|
||||
|
||||
ret = elf_addrenv_alloc(loadinfo, loadinfo->textsize, loadinfo->datasize);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("ERROR: elf_addrenv_alloc() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Read each section into memory that is marked SHF_ALLOC + SHT_NOBITS */
|
||||
|
||||
bvdbg("Loaded sections:\n");
|
||||
|
@ -196,39 +186,14 @@ static inline int elf_loadfile(FAR struct elf_loadinfo_s *loadinfo)
|
|||
|
||||
if (shdr->sh_type != SHT_NOBITS)
|
||||
{
|
||||
/* If CONFIG_ARCH_ADDRENV=y, then 'text' lies in a virtual address
|
||||
* space that may not be in place now. elf_addrenv_select() will
|
||||
* temporarily instantiate that address space.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
ret = elf_addrenv_select(loadinfo);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("ERROR: elf_addrenv_select() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Read the section data from sh_offset to the memory region */
|
||||
|
||||
ret = elf_read(loadinfo, *pptr, shdr->sh_size, shdr->sh_offset);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("Failed to read section %d: %d\n", i, ret);
|
||||
bdbg("ERROR: Failed to read section %d: %d\n", i, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Restore the original address environment */
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
ret = elf_addrenv_restore(loadinfo);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("ERROR: elf_addrenv_restore() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Update sh_addr to point to copy in memory */
|
||||
|
@ -275,7 +240,7 @@ int elf_load(FAR struct elf_loadinfo_s *loadinfo)
|
|||
ret = elf_loadshdrs(loadinfo);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("elf_loadshdrs failed: %d\n", ret);
|
||||
bdbg("ERROR: elf_loadshdrs failed: %d\n", ret);
|
||||
goto errout_with_buffers;
|
||||
}
|
||||
|
||||
|
@ -283,13 +248,36 @@ int elf_load(FAR struct elf_loadinfo_s *loadinfo)
|
|||
|
||||
elf_elfsize(loadinfo);
|
||||
|
||||
/* Allocate memory and load sections into memory */
|
||||
/* Allocate (and zero) memory for the ELF file. */
|
||||
|
||||
ret = elf_addrenv_alloc(loadinfo, loadinfo->textsize, loadinfo->datasize);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("ERROR: elf_addrenv_alloc() failed: %d\n", ret);
|
||||
goto errout_with_buffers;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
/* If CONFIG_ARCH_ADDRENV=y, then the loaded ELF lies in a virtual address
|
||||
* space that may not be in place now. elf_addrenv_select() will
|
||||
* temporarily instantiate that address space.
|
||||
*/
|
||||
|
||||
ret = elf_addrenv_select(loadinfo);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("ERROR: elf_addrenv_select() failed: %d\n", ret);
|
||||
goto errout_with_buffers;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Load ELF section data into memory */
|
||||
|
||||
ret = elf_loadfile(loadinfo);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("elf_loadfile failed: %d\n", ret);
|
||||
goto errout_with_buffers;
|
||||
bdbg("ERROR: elf_loadfile failed: %d\n", ret);
|
||||
goto errout_with_addrenv;
|
||||
}
|
||||
|
||||
/* Load static constructors and destructors. */
|
||||
|
@ -298,14 +286,25 @@ int elf_load(FAR struct elf_loadinfo_s *loadinfo)
|
|||
ret = elf_loadctors(loadinfo);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("elf_loadctors failed: %d\n", ret);
|
||||
goto errout_with_buffers;
|
||||
bdbg("ERROR: elf_loadctors failed: %d\n", ret);
|
||||
goto errout_with_addrenv;
|
||||
}
|
||||
|
||||
ret = elf_loaddtors(loadinfo);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("elf_loaddtors failed: %d\n", ret);
|
||||
bdbg("ERROR: elf_loaddtors failed: %d\n", ret);
|
||||
goto errout_with_addrenv;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
/* Restore the original address environment */
|
||||
|
||||
ret = elf_addrenv_restore(loadinfo);
|
||||
if (ret < 0)
|
||||
{
|
||||
bdbg("ERROR: elf_addrenv_restore() failed: %d\n", ret);
|
||||
goto errout_with_buffers;
|
||||
}
|
||||
#endif
|
||||
|
@ -314,6 +313,11 @@ int elf_load(FAR struct elf_loadinfo_s *loadinfo)
|
|||
|
||||
/* Error exits */
|
||||
|
||||
errout_with_addrenv:
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
(void)elf_addrenv_restore(loadinfo);
|
||||
#endif
|
||||
|
||||
errout_with_buffers:
|
||||
elf_unload(loadinfo);
|
||||
return ret;
|
||||
|
|
Loading…
Reference in a new issue