Skip to main content
PHolt.1
Senior
March 20, 2024
Question

The mysterious __libc_init_array() in Cube IDE - is it only for C++ ??

Supposedly this is only used by C++ but see various threads e.g.

https://www.eevblog.com/forum/microcontrollers/a-question-on-gcc-ld-linker-script-syntax/msg4754165/#msg4754165

https://www.eevblog.com/forum/microcontrollers/how-do-i-enable-link-section-overlap/msg3715957/#msg3715957

https://www.eevblog.com/forum/microcontrollers/mcu-programming-101-writeup/msg5402906/#msg5402906

https://www.eevblog.com/forum/microcontrollers/is-st-cube-ide-a-piece-of-buggy-***/msg5403485/#msg5403485

If you google it, you find a disturbing number of suggestions (nothing concrete!) that in the STM environment, Cube IDE, this function is not only for C++ constructors etc but is also used to initialise some statics in libc.a functions. One suggestion was that malloc() does not work without it. ST does not distribute sources to libc.a although some people on eevblog located probable sources for newlib (dated 1990, IIRC). Much of libc.a is also not re-entrant and needs to be mutexed in any RTOS environment.

Does anyone know the real answer?

    This topic has been closed for replies.

    21 replies

    PHolt.1
    PHolt.1Author
    Senior
    March 21, 2024

    About half of my post above had gone missing.

    PHolt.1
    PHolt.1Author
    Senior
    March 21, 2024

    I posted the linkfile code which connects with __libc_init_array() but it was removed. Anyway, here it is as a graphic:

    Tesla DeLorean
    Guru
    March 21, 2024

    One could size these, and flag a check or objection if that gets to be non-zero.

    The compiler is designed to shovel things into these object/sections as it goes, along with epilogue / prologue code, literals, etc. The linkers designed to filter and collect these things from a stream of output.

    It's going to bend your mind if you start using structured exception handling methods like try/catch/throw...

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    waclawek.jan
    Super User
    March 21, 2024

    > Why?

    Here is an example. You may find it ridiculous; those who want to experience magic, don't. That example doesn't mention another level of magic - supplying mentioned constructor as part of library, i.e. completely out of scope of the end user, who just enjoys the magical results.

    > EXE stuff...

    Sure, but we are talking micro*controllers*.

    > Sort of materials I'd expect would be covered in linker, loader, assemblers, compiler type foundational classes.

    I highly doubt they are in any relevant details.

    Note that it's the academia which disseminated the idea that you are a hopeless loser if you don't use abstraction (as in HAL), encapsulation, information hiding, objects, modelling etc. It's the academia which perpetuates the notion of pure hardware and pure software engineers. Practicing academics are rare and they tend not to be popular types - no wonder, preaching blood, tears, toil and sweat will never attract masses.

    > The kitchen sink approach allows for whatever is built to actually work, without requiring everyone to understand every nuance of the pieces being brought together.

    That's OK. Problem is, that, apparently, at this point *nobody* does.

    JW

    PHolt.1
    PHolt.1Author
    Senior
    March 21, 2024

    The whole reason for me starting this thread was to chase down the multiple statements on the internet - going back years, and in many places - that __libc_init_array() is only for C++, while a few others contradicted this assertion but never giving any detail.

    It has been achieved :grinning_face:

    That's a good link Jan posted, but IIRC it contains some errors e.g.

    Because Newlib is a static library with a separate object file for every function, all you need to do to replace a function is define it in your program. The linker won’t go looking for it in static libraries if it finds it in your code.

    is not true in the ST context; you cannot replace a function in libc.a (or any .a file) unless that function is "weak", and ST compiled entire libc.a as non-weak. I did replace stuff like printf() (posted extensively on eevblog) and used one of the GCC tools to weaken the whole libc.a to enable replacement.

    Only stuff in .o files can be replaced with own-provided functions.

    IMHO, anyone expecting printf() to work without first initialising a UART is going to get into big trouble.

    Q: if you wanted to initialise a UART, how would you arrange it so that calling __libc_init_array() does it? Presumably you need to list the functions which need calling, somewhere.

    PHolt.1
    PHolt.1Author
    Senior
    March 22, 2024

    See here for details

    https://tinyurl.com/25je6rpt

    URL shortened because this forum doesn't like a substring in the EEVBLOG URL :beaming_face_with_smiling_eyes: