This is an automated email from the ASF dual-hosted git repository.

acassis 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 ec78241ebe3 libs/libc/elf: Load an FDPIC object's data into the data 
heap.
ec78241ebe3 is described below

commit ec78241ebe3c1e4906d3d2ff5b820d96150062dc
Author: Marco Casaroli <[email protected]>
AuthorDate: Mon Sep 28 13:15:28 2026 +0200

    libs/libc/elf: Load an FDPIC object's data into the data heap.
    
    An architecture that sets CONFIG_ARCH_USE_DATA_HEAP gives a loaded module
    its data from up_dataheap_memalign(), because the ordinary heap is not where
    that data belongs there.  The ELF loader honours it for every object but an
    FDPIC one: an FDPIC object places its writable segment on its own, and that
    allocation, and the two places that free it, still use lib_memalign() and
    lib_free().  Its text already comes from the text heap.
    
    So an FDPIC module's data goes to the data heap too, and back to it when the
    module is unloaded or removed.
    
    On mps3-an547, which sets both heaps, fdpicxip loaded the data of its two
    instances at 0x1007220 and 0x104e480, in the ordinary heap.  With this 
change
    they are at 0x21000000 and 0x21000180, in the SRAM2 data heap, and both
    instances run.  In a protected build the difference matters: there the
    ordinary heap is kernel memory, and the module takes a data access violation
    on its first access to its data.
    
    Assisted-by: Claude Code:claude-opus-5-5
    Signed-off-by: Marco Casaroli <[email protected]>
---
 libs/libc/elf/elf_load.c   | 12 ++++++++++++
 libs/libc/elf/elf_remove.c |  4 ++++
 libs/libc/elf/elf_unload.c |  4 ++++
 3 files changed, 20 insertions(+)

diff --git a/libs/libc/elf/elf_load.c b/libs/libc/elf/elf_load.c
index 8536e8e5c68..13705a08c5e 100644
--- a/libs/libc/elf/elf_load.c
+++ b/libs/libc/elf/elf_load.c
@@ -869,9 +869,21 @@ int libelf_load(FAR struct mod_loadinfo_s *loadinfo)
 
           if (loadinfo->datasize > 0)
             {
+#  if defined(CONFIG_ARCH_USE_DATA_HEAP) && \
+      defined(CONFIG_ARCH_USE_SEPARATED_SECTION)
+              loadinfo->datastart =
+                (uintptr_t)up_dataheap_memalign(".data",
+                                                loadinfo->dataalign,
+                                                loadinfo->datasize);
+#  elif defined(CONFIG_ARCH_USE_DATA_HEAP)
+              loadinfo->datastart =
+                (uintptr_t)up_dataheap_memalign(loadinfo->dataalign,
+                                                loadinfo->datasize);
+#  else
               loadinfo->datastart =
                 (uintptr_t)lib_memalign(loadinfo->dataalign,
                                         loadinfo->datasize);
+#  endif
               if (!loadinfo->datastart)
                 {
                   berr("ERROR: Failed to allocate the module's data\n");
diff --git a/libs/libc/elf/elf_remove.c b/libs/libc/elf/elf_remove.c
index 849d49a0998..8f7d54bed89 100644
--- a/libs/libc/elf/elf_remove.c
+++ b/libs/libc/elf/elf_remove.c
@@ -180,7 +180,11 @@ int libelf_uninit(FAR struct module_s *modp)
 #endif
             }
 
+#ifdef CONFIG_ARCH_USE_DATA_HEAP
+          up_dataheap_free((FAR void *)modp->dataalloc);
+#else
           lib_free((FAR void *)modp->dataalloc);
+#endif
         }
       else
         {
diff --git a/libs/libc/elf/elf_unload.c b/libs/libc/elf/elf_unload.c
index 9754a4da00f..13168651ee3 100644
--- a/libs/libc/elf/elf_unload.c
+++ b/libs/libc/elf/elf_unload.c
@@ -96,7 +96,11 @@ int libelf_unload(FAR struct mod_loadinfo_s *loadinfo)
 
       if (loadinfo->datastart != 0)
         {
+#ifdef CONFIG_ARCH_USE_DATA_HEAP
+          up_dataheap_free((FAR void *)loadinfo->datastart);
+#else
           lib_free((FAR void *)loadinfo->datastart);
+#endif
           loadinfo->datastart = 0;
         }
 

Reply via email to