Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🧪 support for constructors & destructors #322

Closed
stnolting opened this issue May 20, 2022 · 1 comment · Fixed by #324
Closed

🧪 support for constructors & destructors #322

stnolting opened this issue May 20, 2022 · 1 comment · Fixed by #324
Labels
experimental Experimental feature help wanted Extra attention is needed SW Software-related

Comments

@stnolting
Copy link
Owner

stnolting commented May 20, 2022

@jpf91 @GideonZ

Triggered by the discussion in #313:

Support for constructors and destructors could be "easily" added by extending the .text section of the default NEORV32 linker script (provided by @GideonZ):

    /* .preinit_array */
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array*))
    PROVIDE_HIDDEN (__preinit_array_end = .);

    /* .init_array */
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT(.init_array.*)))
    KEEP (*(.init_array*))
    PROVIDE_HIDDEN (__init_array_end = .);

    /* .fini_array */
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT(.fini_array.*)))
    KEEP (*(.fini_array*))
    PROVIDE_HIDDEN (__fini_array_end = .);

Adding this to the linker script does not hurt as the linker will remove all the included functions if they are not explicitly called.

The con-/destructor array of function pointers have to be called from crt0 before and after main is calles, respectively:

call __libc_init_array
...
call __libc_fini_array

For plain C code it is very unlikely that there are any constructors or destructors at all unless explicitly defined, for example:

void __attribute__((constructor)) test_constructor(void) {
  neorv32_uart1_setup(19200, PARITY_NONE, FLOW_CONTROL_NONE);
  neorv32_uart1_printf("\nHello CONstructor!\n\n");
}

void __attribute__((destructor)) test_destructor(void) {
  neorv32_uart1_setup(19200, PARITY_NONE, FLOW_CONTROL_NONE);
  neorv32_uart1_printf("\nHello DEstructor!\n\n");
}

Adding function calls to __libc_init_array and __libc_fini_array would add some code/library overhead even if there are not constructors/destructors at all.

I am not sure if this should be added to the current setups, which targets plain C code. One option would be to make "define switches" for the according functions calls so the user can explicitly enable this functionality when compiling an application. Another option would be to call the __libc_init_array and __libc_fini_array function directly form main (in C code) is they are required.

I am not sure about c++ applications at all - I have never tested that because I am not really familiar with that. What do you think??

@stnolting stnolting added help wanted Extra attention is needed SW Software-related experimental Experimental feature labels May 20, 2022
@GideonZ
Copy link
Collaborator

GideonZ commented May 20, 2022 via email

@stnolting stnolting linked a pull request May 21, 2022 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
experimental Experimental feature help wanted Extra attention is needed SW Software-related
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants