MainframeReboot commented on issue #12356:
URL: https://github.com/apache/nuttx/issues/12356#issuecomment-2127711351

   > > However, that alone did not solve the issue. I had to remove the calls 
`exec_ctores()` and `atexit(exec_dtors)` from `crt0.c` in order to not crash on 
ELF load.
   > 
   > exec_ctors() is really simple, but it depends on a table of constructor 
addresses created by the build logic. These are defined by 
binfmt/libelf/gnu-elf.ld or similar:
   > 
   > ```
   > /* Linker defined symbols to .ctors and .dtors */
   > 
   > extern initializer_t _sctors[];
   > extern initializer_t _ectors[];
   > extern initializer_t _sdtors[];
   > extern initializer_t _edtors[];
   > ```
   > 
   > Check whatever linker script you use to build the elf modules. Check that 
those symbols exist in the module.
   > 
   > These define a table of constructor and destructor address. Constructors 
start at _sctors and end at _ectors. Make sure that there are constructors in 
the table.
   > 
   > Issues with atexit() may be like those of #1263. I don't know the state of 
that issue. The function called by atexit() calls the destructors. So more 
likely that is the same issue as with the list of destructors.
   > 
   > > Regardless, I can live with NuttX kernel build that has no C++ static 
constructor support given everything else appears to be working flawlessly.
   > 
   > But you shouldn't have to!
   
   I decided not to settle and poked around more to see if I can get static 
constructor support to work but no luck so far.
   
   I have taken a look and `CONFIG_BINFMT_CONSTRUCTORS` is not set in my config 
anymore.
   
   The segmentation fault appears to happen inside the function `exec_ctors()` 
the moment `(*ctor)()` is executed.  This is called inside `__start()` that is 
provided by `crt0.o`.
   
   I dumped helloxx and examined the symbol table to make sure .ctors was there 
and it is:
   
   
![image](https://github.com/apache/nuttx/assets/168458700/0bf34605-a960-414f-b91a-7b80b62f4661)
   
   My linker script is based on the linker script from the Fully Linking for 
NuttX apps article by @lupyuen and looks as follows:
   
   ```
   SECTIONS
   {
     . = 0xC0000000;
     .text :
       {
         _stext = . ;
         *(.text)
         *(.text.*)
         *(.gnu.warning)
         *(.stub)
         *(.glue_7)
         *(.glue_7t)
         *(.jcr)
   
         /* C++ support:  The .init and .fini sections contain specific logic
          * to manage static constructors and destructors.
          */
   
         *(.gnu.linkonce.t.*)
         KEEP(*(.init))             /* Old ABI */
         KEEP(*(.fini))             /* Old ABI */
         _etext = . ;
       }
   
     .rodata :
       {
         _srodata = . ;
         *(.rodata)
         *(.rodata1)
         *(.rodata.*)
         *(.gnu.linkonce.r*)
         _erodata = . ;
       }
   
     . = 0xC0400000;
     .data :
       {
         _sdata = . ;
         *(.data)
         *(.data1)
         *(.data.*)
         *(.gnu.linkonce.d*)
         . = ALIGN(4);
         _edata = . ;
       }
   
     /* C++ support. For each global and static local C++ object,
      * GCC creates a small subroutine to construct the object. Pointers
      * to these routines (not the routines themselves) are stored as
      * simple, linear arrays in the .ctors section of the object file.
      * Similarly, pointers to global/static destructor routines are
      * stored in .dtors.
      */
   
     .ctors :
       {
         _sctors = . ;
         KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*) 
SORT_BY_INIT_PRIORITY(.ctors.*)))
         KEEP(*(.init_array .ctors))
         _ectors = . ;
       }
   
     .dtors :
       {
         _sdtors = . ;
         KEEP (*(.dtors))       /* Old ABI:  Unallocated */
         KEEP (*(.fini_array))  /* New ABI:  Allocated */
         KEEP (*(SORT(.fini_array.*)))
         _edtors = . ;
       }
   
     .bss :
       {
         _sbss = . ;
         *(.bss)
         *(.bss.*)
         *(.sbss)
         *(.sbss.*)
         *(.gnu.linkonce.b*)
         *(COMMON)
         _ebss = . ;
       }
   
     /* Thread local storage support */
     .tdata : {
         _stdata = ABSOLUTE(.);
         KEEP (*(.tdata .tdata.* .gnu.linkonce.td.*));
         _etdata = ABSOLUTE(.);
     }
   
     .tbss : {
         _stbss = ABSOLUTE(.);
         KEEP (*(.tbss .tbss.* .gnu.linkonce.tb.* .tcommon));
         _etbss = ABSOLUTE(.);
     }
   
       /* Stabs debugging sections.    */
   
       .stab 0 : { *(.stab) }
       .stabstr 0 : { *(.stabstr) }
       .stab.excl 0 : { *(.stab.excl) }
       .stab.exclstr 0 : { *(.stab.exclstr) }
       .stab.index 0 : { *(.stab.index) }
       .stab.indexstr 0 : { *(.stab.indexstr) }
       .comment 0 : { *(.comment) }
       .debug_abbrev 0 : { *(.debug_abbrev) }
       .debug_info 0 : { *(.debug_info) }
       .debug_line 0 : { *(.debug_line) }
       .debug_pubnames 0 : { *(.debug_pubnames) }
       .debug_aranges 0 : { *(.debug_aranges) }
   }
   ```
   
   I can confirm the initial address `ctor` points to is `0xC0400020` which 
matches the symbol table so I'm not quite sure what I'm missing now...


-- 
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: commits-unsubscr...@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to