xref: /netbsd-src/external/gpl3/gcc.old/dist/libgcc/config/m32r/initfini.c (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
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