Update from main archive 961219
[glibc.git] / csu / initfini.c
blob0fdfe5dcb83f7fdbbb9014678f730df47cabddba
1 /* Special .init and .fini section support.
2 Copyright (C) 1995, 1996 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it
6 and/or modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
10 In addition to the permissions in the GNU Library General Public
11 License, the Free Software Foundation gives you unlimited
12 permission to link the compiled version of this file with other
13 programs, and to distribute those programs without any restriction
14 coming from the use of this file. (The Library General Public
15 License restrictions do apply in other respects; for example, they
16 cover modification of the file, and distribution when not linked
17 into another program.)
19 The GNU C Library is distributed in the hope that it will be
20 useful, but WITHOUT ANY WARRANTY; without even the implied warranty
21 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU Library General Public License for more details.
24 You should have received a copy of the GNU Library General Public
25 License along with the GNU C Library; see the file COPYING.LIB. If not,
26 write to the Free Software Foundation, 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. */
29 /* This file is compiled into assembly code which is then surrounded by the
30 lines `cat > crtcommon.tmp <<\EOF_common' and `EOF_common' and thus
31 becomes a shell script which creates three files of assembly code.
33 * The first file is crti.s-new; this puts a function prologue at the
34 beginning of the .init and .fini sections and defines global symbols for
35 those addresses, so they can be called as functions.
37 * The second file is crtn.s-new; this puts the corresponding function
38 epilogues in the .init and .fini sections.
40 * The third file is crtcommon.tmp, which is whatever miscellaneous cruft
41 the compiler generated at the end; it should be appended to both crti.s-new
42 and crtn.s-new. */
44 #include <stdlib.h>
47 #ifdef HAVE_ELF
48 /* These declarations make the functions go in the right sections when
49 we define them below. GCC syntax does not allow the attribute
50 specifications to be in the function definitions themselves. */
51 void _init (void) __attribute__ ((section (".init")));
52 void _fini (void) __attribute__ ((section (".fini")));
54 #define SECTION(x) /* Put nothing extra before the defn. */
56 #else
57 /* Some non-ELF systems support .init and .fini sections,
58 but the __attribute__ syntax only works for ELF. */
59 #define SECTION(x) asm (".section " x);
60 #endif
62 /* End the here document containing the initial common code.
63 Then move the output file crtcommon.tmp to crti.s-new and crtn.s-new. */
64 asm ("\nEOF_common\n\
65 rm -f crti.s-new crtn.s-new\n\
66 mv crtcommon.tmp crti.s-new\n\
67 cp crti.s-new crtn.s-new");
69 /* Extract a `.end' if one is produced by the compiler. */
70 asm ("fgrep .end >/dev/null 2>&1 <<\\EOF.end && need_end=yes");
71 void
72 useless_function (void)
74 return;
76 asm ("\nEOF.end\n");
78 /* Find out how much alignment is produced by the compiler. */
79 asm ("align=`awk '$1==\".align\" { if ($2>max) max=$2; } END { print max; }' \
80 <<\\EOF.align");
81 void
82 useless_function2 (void (*foo) (void))
84 if (foo)
85 (*foo) ();
87 asm ("\nEOF.align\n`\n");
89 /* Append the .init prologue to crti.s-new. */
90 asm ("cat >> crti.s-new <<\\EOF.crti.init");
92 SECTION (".init")
93 void
94 _init (void)
96 /* We cannot use the normal constructor mechanism in gcrt1.o because it
97 appears before crtbegin.o in the link, so the header elt of .ctors
98 would come after the elt for __gmon_start__. One approach is for
99 gcrt1.o to reference a symbol which would be defined by some library
100 module which has a constructor; but then user code's constructors
101 would come first, and not be profiled. */
102 extern void __gmon_start__ (void); weak_extern (__gmon_start__)
103 if (__gmon_start__)
104 __gmon_start__ ();
106 /* End the here document containing the .init prologue code.
107 Then fetch the .section directive just written and append that
108 to crtn.s-new, followed by the function epilogue. */
109 asm ("\n\
110 EOF.crti.init\n\
111 test -n \"$align\" && echo .align $align >> crti.s-new\n\
112 test -n \"$need_end\" && echo .end _init >> crti.s-new\n\
113 fgrep .init crti.s-new >>crtn.s-new\n\
114 fgrep -v .end >> crtn.s-new <<\\EOF.crtn.init");
117 /* End the here document containing the .init epilogue code.
118 Then append the .fini prologue to crti.s-new. */
119 asm ("\nEOF.crtn.init\
121 cat >> crti.s-new <<\\EOF.crti.fini");
123 SECTION (".fini")
124 void
125 _fini (void)
127 /* End the here document containing the .fini prologue code.
128 Then fetch the .section directive just written and append that
129 to crtn.s-new, followed by the function epilogue. */
130 asm ("\nEOF.crti.fini\n\
131 test -n \"$align\" && echo .align $align >> crti.s-new\n\
132 test -n \"$need_end\" && echo .end _fini >> crti.s-new\n\
133 cat > /dev/null <<\\EOF.fini.skip");
136 /* Let GCC know that _fini is not a leaf function by having a dummy
137 function call here. We arrange for this call to be omitted from
138 either crt file. */
139 extern void i_am_not_a_leaf (void);
140 i_am_not_a_leaf ();
143 asm ("\nEOF.fini.skip\
145 fgrep .fini crti.s-new >>crtn.s-new\n\
146 fgrep -v .end >> crtn.s-new <<\\EOF.crtn.fini");
149 /* End the here document containing the .fini epilogue code.
150 Finally, put the remainder of the generated assembly into crtcommon.tmp. */
151 asm ("\nEOF.crtn.fini\
153 cat > crtcommon.tmp <<\\EOF_common");