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;

Reply via email to