Skip to content

Commit e384a6a

Browse files
pussuwxiaoxiang781216
authored andcommitted
libs/modlib.c: Set VMA for empty and unallocated sections
This fixes issue where empty and unallocated sections are left without a VMA. Some relocations depend on the section VMA being set even if there is no data there, as the binary can refer to the symbols. Linker defined symbols do not contain data -> they can produce empty sections. This issue is seen when building a loadable file which declares _sctors / _sdtors linker defined symbols for ctor/dtor sections which are empty. crt0 references these symbols, so they need to be relocated, but the section VMA is not set -> they go outside of the addressable range of the user binary causing a potential crash.
1 parent ef350af commit e384a6a

File tree

1 file changed

+38
-7
lines changed

1 file changed

+38
-7
lines changed

libs/libc/modlib/modlib_load.c

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ static int modlib_section_alloc(FAR struct mod_loadinfo_s *loadinfo,
128128
}
129129
}
130130

131-
return 0;
131+
return OK;
132132
}
133133
#endif
134134

@@ -266,14 +266,47 @@ static int modlib_vma2lma(FAR struct mod_loadinfo_s *loadinfo,
266266
shdr->sh_offset <= phdr->p_offset + phdr->p_filesz)
267267
{
268268
*lma = phdr->p_paddr + shdr->sh_addr - phdr->p_vaddr;
269-
return 0;
269+
return OK;
270270
}
271271
}
272272

273273
return -ENOENT;
274274
}
275275
#endif
276276

277+
/****************************************************************************
278+
* Name: modlib_set_emptysect_vma
279+
*
280+
* Description:
281+
* Set VMA for empty and unallocated sections, some relocations might
282+
* depend on this.
283+
*
284+
* Returned Value:
285+
* None.
286+
*
287+
****************************************************************************/
288+
289+
static void modlib_set_emptysect_vma(FAR struct mod_loadinfo_s *loadinfo,
290+
int section)
291+
{
292+
FAR Elf_Shdr *shdr = &loadinfo->shdr[section];
293+
294+
/* Set the section as data or text, depending on SHF_WRITE */
295+
296+
if ((shdr->sh_flags & SHF_WRITE) != 0
297+
#ifdef CONFIG_ARCH_HAVE_TEXT_HEAP_WORD_ALIGNED_READ
298+
|| (shdr->sh_flags & SHF_EXECINSTR) == 0
299+
#endif
300+
)
301+
{
302+
shdr->sh_addr = loadinfo->datastart;
303+
}
304+
else
305+
{
306+
shdr->sh_addr = loadinfo->textalloc;
307+
}
308+
}
309+
277310
/****************************************************************************
278311
* Name: modlib_loadfile
279312
*
@@ -339,13 +372,11 @@ static inline int modlib_loadfile(FAR struct mod_loadinfo_s *loadinfo)
339372
* execution
340373
*/
341374

342-
if (shdr->sh_size == 0)
375+
if ((shdr->sh_flags & SHF_ALLOC) == 0 || shdr->sh_size == 0)
343376
{
344-
continue;
345-
}
377+
/* Set the VMA regardless */
346378

347-
if ((shdr->sh_flags & SHF_ALLOC) == 0)
348-
{
379+
modlib_set_emptysect_vma(loadinfo, i);
349380
continue;
350381
}
351382

0 commit comments

Comments
 (0)