update from main archive 961126
[platform/upstream/glibc.git] / csu / initfini.c
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.
4
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.
9
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 Libraty 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.)
18
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.
23
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.  */
28
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.
32
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.
36
37    * The second file is crtn.s-new; this puts the corresponding function
38    epilogues in the .init and .fini sections.
39
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.  */
43
44 #include <stdlib.h>
45
46
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")));
53
54 #define SECTION(x)              /* Put nothing extra before the defn.  */
55
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
61
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");
68
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)
73 {
74   return;
75 }
76 asm ("\nEOF.end\n");
77
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))
83 {
84   if (foo)
85     (*foo) ();
86 }
87 asm ("\nEOF.align\n`\n");
88
89 /* Append the .init prologue to crti.s-new.  */
90 asm ("cat >> crti.s-new <<\\EOF.crti.init");
91
92 SECTION (".init")
93 void
94 _init (void)
95 {
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__ ();
105
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");
115 }
116
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\
120 \n\
121 cat >> crti.s-new <<\\EOF.crti.fini");
122
123 SECTION (".fini")
124 void
125 _fini (void)
126 {
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");
134
135   {
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 ();
141   }
142
143   asm ("\nEOF.fini.skip\
144 \n\
145         fgrep .fini crti.s-new >>crtn.s-new\n\
146         fgrep -v .end >> crtn.s-new <<\\EOF.crtn.fini");
147 }
148
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\
152 \n\
153 cat > crtcommon.tmp <<\\EOF_common");