136ac495dSmrg /* .init/.fini section handling + C++ global constructor/destructor handling.
236ac495dSmrg This file is based on crtstuff.c, sol2-crti.S, sol2-crtn.S.
336ac495dSmrg
4*8feb0f0bSmrg Copyright (C) 1996-2020 Free Software Foundation, Inc.
536ac495dSmrg
636ac495dSmrg This file is part of GCC.
736ac495dSmrg
836ac495dSmrg GCC is free software; you can redistribute it and/or modify
936ac495dSmrg it under the terms of the GNU General Public License as published by
1036ac495dSmrg the Free Software Foundation; either version 3, or (at your option)
1136ac495dSmrg any later version.
1236ac495dSmrg
1336ac495dSmrg GCC is distributed in the hope that it will be useful,
1436ac495dSmrg but WITHOUT ANY WARRANTY; without even the implied warranty of
1536ac495dSmrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1636ac495dSmrg GNU General Public License for more details.
1736ac495dSmrg
1836ac495dSmrg Under Section 7 of GPL version 3, you are granted additional
1936ac495dSmrg permissions described in the GCC Runtime Library Exception, version
2036ac495dSmrg 3.1, as published by the Free Software Foundation.
2136ac495dSmrg
2236ac495dSmrg You should have received a copy of the GNU General Public License and
2336ac495dSmrg a copy of the GCC Runtime Library Exception along with this program;
2436ac495dSmrg see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
2536ac495dSmrg <http://www.gnu.org/licenses/>. */
2636ac495dSmrg
2736ac495dSmrg /* Declare a pointer to void function type. */
2836ac495dSmrg typedef void (*func_ptr) (void);
2936ac495dSmrg
3036ac495dSmrg #ifdef CRT_INIT
3136ac495dSmrg
3236ac495dSmrg /* NOTE: In order to be able to support SVR4 shared libraries, we arrange
3336ac495dSmrg to have one set of symbols { __CTOR_LIST__, __DTOR_LIST__, __CTOR_END__,
3436ac495dSmrg __DTOR_END__ } per root executable and also one set of these symbols
3536ac495dSmrg per shared library. So in any given whole process image, we may have
3636ac495dSmrg multiple definitions of each of these symbols. In order to prevent
3736ac495dSmrg these definitions from conflicting with one another, and in order to
3836ac495dSmrg ensure that the proper lists are used for the initialization/finalization
3936ac495dSmrg of each individual shared library (respectively), we give these symbols
4036ac495dSmrg only internal (i.e. `static') linkage, and we also make it a point to
4136ac495dSmrg refer to only the __CTOR_END__ symbol in crtfini.o and the __DTOR_LIST__
4236ac495dSmrg symbol in crtinit.o, where they are defined. */
4336ac495dSmrg
4436ac495dSmrg static func_ptr __CTOR_LIST__[1]
4536ac495dSmrg __attribute__ ((used, section (".ctors")))
4636ac495dSmrg = { (func_ptr) (-1) };
4736ac495dSmrg
4836ac495dSmrg static func_ptr __DTOR_LIST__[1]
4936ac495dSmrg __attribute__ ((used, section (".dtors")))
5036ac495dSmrg = { (func_ptr) (-1) };
5136ac495dSmrg
5236ac495dSmrg /* Run all the global destructors on exit from the program. */
5336ac495dSmrg
5436ac495dSmrg /* Some systems place the number of pointers in the first word of the
5536ac495dSmrg table. On SVR4 however, that word is -1. In all cases, the table is
5636ac495dSmrg null-terminated. On SVR4, we start from the beginning of the list and
5736ac495dSmrg invoke each per-compilation-unit destructor routine in order
5836ac495dSmrg until we find that null.
5936ac495dSmrg
6036ac495dSmrg Note that this function MUST be static. There will be one of these
6136ac495dSmrg functions in each root executable and one in each shared library, but
6236ac495dSmrg although they all have the same code, each one is unique in that it
6336ac495dSmrg refers to one particular associated `__DTOR_LIST__' which belongs to the
6436ac495dSmrg same particular root executable or shared library file. */
6536ac495dSmrg
6636ac495dSmrg static void __do_global_dtors (void)
6736ac495dSmrg asm ("__do_global_dtors") __attribute__ ((used, section (".text")));
6836ac495dSmrg
6936ac495dSmrg static void
__do_global_dtors(void)7036ac495dSmrg __do_global_dtors (void)
7136ac495dSmrg {
7236ac495dSmrg func_ptr *p;
7336ac495dSmrg
7436ac495dSmrg for (p = __DTOR_LIST__ + 1; *p; p++)
7536ac495dSmrg (*p) ();
7636ac495dSmrg }
7736ac495dSmrg
7836ac495dSmrg /* .init section start.
7936ac495dSmrg This must appear at the start of the .init section. */
8036ac495dSmrg
8136ac495dSmrg asm ("\n\
8236ac495dSmrg .section .init,\"ax\",@progbits\n\
8336ac495dSmrg .balign 4\n\
8436ac495dSmrg .global __init\n\
8536ac495dSmrg __init:\n\
8636ac495dSmrg push fp\n\
8736ac495dSmrg push lr\n\
8836ac495dSmrg mv fp,sp\n\
8936ac495dSmrg seth r0, #shigh(__fini)\n\
9036ac495dSmrg add3 r0, r0, #low(__fini)\n\
9136ac495dSmrg bl atexit\n\
9236ac495dSmrg .fillinsn\n\
9336ac495dSmrg ");
9436ac495dSmrg
9536ac495dSmrg /* .fini section start.
9636ac495dSmrg This must appear at the start of the .init section. */
9736ac495dSmrg
9836ac495dSmrg asm ("\n\
9936ac495dSmrg .section .fini,\"ax\",@progbits\n\
10036ac495dSmrg .balign 4\n\
10136ac495dSmrg .global __fini\n\
10236ac495dSmrg __fini:\n\
10336ac495dSmrg push fp\n\
10436ac495dSmrg push lr\n\
10536ac495dSmrg mv fp,sp\n\
10636ac495dSmrg bl __do_global_dtors\n\
10736ac495dSmrg .fillinsn\n\
10836ac495dSmrg ");
10936ac495dSmrg
11036ac495dSmrg #endif /* CRT_INIT */
11136ac495dSmrg
11236ac495dSmrg #ifdef CRT_FINI
11336ac495dSmrg
11436ac495dSmrg /* Put a word containing zero at the end of each of our two lists of function
11536ac495dSmrg addresses. Note that the words defined here go into the .ctors and .dtors
11636ac495dSmrg sections of the crtend.o file, and since that file is always linked in
11736ac495dSmrg last, these words naturally end up at the very ends of the two lists
11836ac495dSmrg contained in these two sections. */
11936ac495dSmrg
12036ac495dSmrg static func_ptr __CTOR_END__[1]
12136ac495dSmrg __attribute__ ((used, section (".ctors")))
12236ac495dSmrg = { (func_ptr) 0 };
12336ac495dSmrg
12436ac495dSmrg static func_ptr __DTOR_END__[1]
12536ac495dSmrg __attribute__ ((used, section (".dtors")))
12636ac495dSmrg = { (func_ptr) 0 };
12736ac495dSmrg
12836ac495dSmrg /* Run all global constructors for the program.
12936ac495dSmrg Note that they are run in reverse order. */
13036ac495dSmrg
13136ac495dSmrg static void __do_global_ctors (void)
13236ac495dSmrg asm ("__do_global_ctors") __attribute__ ((used, section (".text")));
13336ac495dSmrg
13436ac495dSmrg static void
__do_global_ctors(void)13536ac495dSmrg __do_global_ctors (void)
13636ac495dSmrg {
13736ac495dSmrg func_ptr *p;
13836ac495dSmrg
13936ac495dSmrg for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
14036ac495dSmrg (*p) ();
14136ac495dSmrg }
14236ac495dSmrg
14336ac495dSmrg /* .init section end.
14436ac495dSmrg This must live at the end of the .init section. */
14536ac495dSmrg
14636ac495dSmrg asm ("\n\
14736ac495dSmrg .section .init,\"ax\",@progbits\n\
14836ac495dSmrg bl __do_global_ctors\n\
14936ac495dSmrg mv sp,fp\n\
15036ac495dSmrg pop lr\n\
15136ac495dSmrg pop fp\n\
15236ac495dSmrg jmp lr\n\
15336ac495dSmrg .fillinsn\n\
15436ac495dSmrg ");
15536ac495dSmrg
15636ac495dSmrg /* .fini section end.
15736ac495dSmrg This must live at the end of the .fini section. */
15836ac495dSmrg
15936ac495dSmrg asm ("\n\
16036ac495dSmrg .section .fini,\"ax\",@progbits\n\
16136ac495dSmrg mv sp,fp\n\
16236ac495dSmrg pop lr\n\
16336ac495dSmrg pop fp\n\
16436ac495dSmrg jmp lr\n\
16536ac495dSmrg .fillinsn\n\
16636ac495dSmrg ");
16736ac495dSmrg
16836ac495dSmrg #endif /* CRT_FINI */
169