This is an automated email from the ASF dual-hosted git repository.
xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new fae893d4115 libs/libc/elf: Give a shared object a word alignment, not
zero.
fae893d4115 is described below
commit fae893d4115e43fcf530243b391f7708cc71a6af
Author: Marco Casaroli <[email protected]>
AuthorDate: Sun Aug 23 22:55:59 2026 +0200
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) <[email protected]>
Signed-off-by: Marco Casaroli <[email protected]>
---
libs/libc/elf/elf_load.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/libs/libc/elf/elf_load.c b/libs/libc/elf/elf_load.c
index c58f8060ade..e01e2fd7489 100644
--- a/libs/libc/elf/elf_load.c
+++ b/libs/libc/elf/elf_load.c
@@ -239,6 +239,20 @@ static void libelf_elfsize(FAR struct mod_loadinfo_s
*loadinfo, bool alloc)
}
}
+ /* An ET_DYN object is sized from its program headers, which give no
+ * section alignment. A word is enough.
+ */
+
+ if (loadinfo->textalign == 0)
+ {
+ loadinfo->textalign = sizeof(uintptr_t);
+ }
+
+ if (loadinfo->dataalign == 0)
+ {
+ loadinfo->dataalign = sizeof(uintptr_t);
+ }
+
/* Save the allocation size */
loadinfo->textsize = textsize;