Skip to content

Commit fae893d

Browse files
casarolixiaoxiang781216
authored andcommitted
libs/libc/elf: Give a shared object a word alignment, not zero.
libelf_elfsize() takes textalign and dataalign from the section headers, which only the ET_REL path walks. An ET_DYN object is sized from its program headers instead, so both fields stay at zero, and the allocation a few lines later asks for that alignment: loadinfo->textalloc = lib_memalign(loadinfo->textalign, ...); Zero is not a valid alignment, and every path that receives it divides by it. mm_memalign() accepts zero as a power of two, because 0 & -0 is 0, then takes the "alignment <= MM_ALIGN" branch and evaluates "((uintptr_t)ptr) % alignment" in a DEBUGASSERT. With CONFIG_MM_HEAP_MEMPOOL and a pool that fits the request the object never reaches that branch and gets ALIGN_UP(blk, 0) instead, which is ((blk - 1) / 0) * 0. On Cortex-M this is usually invisible: UDIV returns zero for a division by zero unless CCR.DIV_0_TRP is set, which NuttX does not set, so the assertion compares zero against zero and passes. It is a SIGFPE on the simulator, and the mempool path returns a null pointer wherever the division yields zero, which the loader reports as -ENOMEM. Ask for a natural word when the program headers gave nothing. p_align is the linker's page granularity, not a section requirement, so honouring it would cost a page per module for no gain, and the sections of a shared object need no more than a word. Built for mps3-an547:picostest, which is CONFIG_ELF with CONFIG_PIC. Runtime evidence on hardware follows. Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
1 parent bdeb262 commit fae893d

1 file changed

Lines changed: 14 additions & 0 deletions

File tree

libs/libc/elf/elf_load.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,20 @@ static void libelf_elfsize(FAR struct mod_loadinfo_s *loadinfo, bool alloc)
239239
}
240240
}
241241

242+
/* An ET_DYN object is sized from its program headers, which give no
243+
* section alignment. A word is enough.
244+
*/
245+
246+
if (loadinfo->textalign == 0)
247+
{
248+
loadinfo->textalign = sizeof(uintptr_t);
249+
}
250+
251+
if (loadinfo->dataalign == 0)
252+
{
253+
loadinfo->dataalign = sizeof(uintptr_t);
254+
}
255+
242256
/* Save the allocation size */
243257

244258
loadinfo->textsize = textsize;

0 commit comments

Comments
 (0)