LingaoM opened a new pull request, #19882:
URL: https://github.com/apache/nuttx/pull/19882

   Loadable ELF tasks currently do not run module init/fini arrays when they 
are executed through the binfmt path. This is enough for many C modules, but 
C++ modules rely on those arrays for global constructors and destructors, so 
objects with static storage duration are not initialized or finalized correctly.
   
   C++ exceptions on the x86_64 SIM target also need the module DWARF unwind 
data to be visible to the host unwinder. The loaded .eh_frame section is 
relocated by the ELF loader, but it is not registered with libgcc unwinder 
state, so stack unwinding through a loaded module cannot find the FDEs needed 
for C++ catch handling.
   
   Run loadable ELF init arrays from nxtask_startup() before entering the task 
main function and run fini arrays when the task returns or exits. The fini 
array count is cleared before callbacks are invoked so the same module 
destructors are not called twice on normal return followed by binfmt unload.
   
   Add an optional CONFIG_LIBC_ELF_EH_FRAME path for x86_64 SIM that registers 
a loaded module .eh_frame section after relocation and deregisters it on unload 
or failed load cleanup. Keep the option disabled by default and limited to SIM, 
where the host DWARF unwinder APIs are available.
   
   Preserve .eh_frame and .gcc_except_table in the loadable ELF linker script 
so exception metadata remains available after module linking. Also accept 
R_X86_64_NONE as a no-op relocation in the SIM x86_64 relocator; some C++ 
objects can contain those entries and rejecting them prevents otherwise valid 
modules from loading.
   
   The apps-side loadelf demo and stress tests are carried in the companion 
apps commit:
   
     
https://github.com/LingaoM/nuttx-apps/commit/1c75943922f5dfb3818ddb8594c9d3f1a0b9bd87
   
   Testing:
   
     Host:
   
       Ubuntu 22.04 x86_64
   
     Board/config:
   
       apps-side sim/loadelfdemo
   
     Apps test code:
   
       
https://github.com/LingaoM/nuttx-apps/commit/1c75943922f5dfb3818ddb8594c9d3f1a0b9bd87
   
     Configuration highlights:
   
       CONFIG_ELF=y
       CONFIG_LIBC_EXECFUNCS=y
       CONFIG_EXECFUNCS_HAVE_SYMTAB=y
       # CONFIG_EXECFUNCS_SYSTEM_SYMTAB is not set
       CONFIG_BINFMT_CONSTRUCTORS=y
       CONFIG_CXX_EXCEPTION=y
       CONFIG_CXX_RTTI=y
       CONFIG_CXX_WCHAR=y
       CONFIG_LIBC_ELF_EH_FRAME=y
       CONFIG_LIBCXXNONE=y
       CONFIG_LIBMINIABI=y
       CONFIG_SIM_TOOLCHAIN_GCC=y
   
     Build and export:
   
       make distclean
       ./tools/configure.sh -l ../nuttx-apps/sim/loadelfdemo
       make olddefconfig KCONFIG_OLDDEFCONFIG="python3 -m olddefconfig"
       make -j16
       make export
   
     External ELF samples built from the NuttX export:
   
       make -C ../nuttx-apps/examples/loadelfdemo/samples/loadelf_sample \
         clean install check
       make -C ../nuttx-apps/examples/loadelfdemo/samples/loadelf_cpp_stress \
         clean install check
   
     Runtime test:
   
       printf 'loadelfdemo loadelf_sample 10 20 30\n\
       loadelfdemo loadelf_sample 1 2\n\
       loadelfdemo loadelf_cpp_stress\n\
       poweroff\n' | timeout 80s ./nuttx
   
     Observed result:
   
       loadelf_sample loaded successfully twice, with the second run reusing the
       existing /system/bin mount. loadelf_cpp_stress passed all checks 
including
       global constructors, STL containers, RTTI, exceptions, iostream, regex,
       filesystem, thread/condition_variable, future/async, and global 
destructor
       execution.
   
   <img width="1634" height="1638" alt="image" 
src="https://github.com/user-attachments/assets/ebc05130-e04e-4bb7-8901-7533805a95ed";
 />
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to