Update UD main archive 960805
[kopensolaris-gnu/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 and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB.  If
17 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
18 Cambridge, MA 02139, USA.  */
19
20 /* This file is compiled into assembly code which is then surrounded by the
21    lines `cat > crtcommon.tmp <<\EOF_common' and `EOF_common' and thus
22    becomes a shell script which creates three files of assembly code.
23
24    * The first file is crti.s-new; this puts a function prologue at the
25    beginning of the .init and .fini sections and defines global symbols for
26    those addresses, so they can be called as functions.
27
28    * The second file is crtn.s-new; this puts the corresponding function
29    epilogues in the .init and .fini sections.
30
31    * The third file is crtcommon.tmp, which is whatever miscellaneous cruft
32    the compiler generated at the end; it should be appended to both crti.s-new
33    and crtn.s-new.  */
34
35 #include <stdlib.h>
36
37
38 #ifdef HAVE_ELF
39 /* These declarations make the functions go in the right sections when
40    we define them below.  GCC syntax does not allow the attribute
41    specifications to be in the function definitions themselves.  */
42 void _init (void) __attribute__ ((section (".init")));
43 void _fini (void) __attribute__ ((section (".fini")));
44
45 #define SECTION(x)              /* Put nothing extra before the defn.  */
46
47 #else
48 /* Some non-ELF systems support .init and .fini sections,
49    but the __attribute__ syntax only works for ELF.  */
50 #define SECTION(x) asm (".section " x);
51 #endif
52
53 /* End the here document containing the initial common code.
54    Then move the output file crtcommon.tmp to crti.s-new and crtn.s-new.  */
55 asm ("\nEOF_common\n\
56 rm -f crti.s-new crtn.s-new\n\
57 mv crtcommon.tmp crti.s-new\n\
58 cp crti.s-new crtn.s-new");
59
60 /* Extract a `.end' if one is produced by the compiler.  */
61 asm ("fgrep .end >/dev/null 2>&1 <<\\EOF.end && need_end=yes");
62 void
63 useless_function (void)
64 {
65   return;
66 }
67 asm ("\nEOF.end\n");
68
69 /* Find out how much alignment is produced by the compiler.  */
70 asm ("align=`awk '$1==\".align\" { if ($2>max) max=$2; } END { print max; }' \
71 <<\\EOF.align");
72 void
73 useless_function2 (void (*foo) (void))
74 {
75   if (foo)
76     (*foo) ();
77 }
78 asm ("\nEOF.align\n`\n");
79
80 /* Append the .init prologue to crti.s-new.  */
81 asm ("cat >> crti.s-new <<\\EOF.crti.init");
82
83 SECTION (".init")
84 void
85 _init (void)
86 {
87   /* We cannot use the normal constructor mechanism in gcrt1.o because it
88      appears before crtbegin.o in the link, so the header elt of .ctors
89      would come after the elt for __gmon_start__.  One approach is for
90      gcrt1.o to reference a symbol which would be defined by some library
91      module which has a constructor; but then user code's constructors
92      would come first, and not be profiled.  */
93   extern void __gmon_start__ (void); weak_extern (__gmon_start__)
94   if (__gmon_start__)
95     __gmon_start__ ();
96
97   /* End the here document containing the .init prologue code.
98      Then fetch the .section directive just written and append that
99      to crtn.s-new, followed by the function epilogue.  */
100   asm ("\n\
101 EOF.crti.init\n\
102         test -n \"$align\" && echo .align $align >> crti.s-new\n\
103         test -n \"$need_end\" && echo .end _init >> crti.s-new\n\
104         fgrep .init crti.s-new >>crtn.s-new\n\
105         fgrep -v .end >> crtn.s-new <<\\EOF.crtn.init");
106 }
107
108 /* End the here document containing the .init epilogue code.
109    Then append the .fini prologue to crti.s-new.  */
110 asm ("\nEOF.crtn.init\
111 \n\
112 cat >> crti.s-new <<\\EOF.crti.fini");
113
114 /* Global variable which says whether we have a statically or dynamically
115    linked program.  If > 0, static, for < 0 dynamic, == 0 means yet to
116    be determined (see init-first.c).  */
117 int __libc_is_static = 0;
118
119 SECTION (".fini")
120 void
121 _fini (void)
122 {
123   /* End the here document containing the .fini prologue code.
124      Then fetch the .section directive just written and append that
125      to crtn.s-new, followed by the function epilogue.  */
126   asm ("\nEOF.crti.fini\n\
127 test -n \"$align\" && echo .align $align >> crti.s-new\n\
128 test -n \"$need_end\" && echo .end _fini >> crti.s-new\n\
129 cat > /dev/null <<\\EOF.fini.skip");
130
131   {
132     /* Let GCC know that _fini is not a leaf function by having a dummy
133        function call here.  We arrange for this call to be omitted from
134        either crt file.  */
135     extern void i_am_not_a_leaf (void);
136     i_am_not_a_leaf ();
137   }
138
139   asm ("\nEOF.fini.skip\
140 \n\
141         fgrep .fini crti.s-new >>crtn.s-new\n\
142         fgrep -v .end >> crtn.s-new <<\\EOF.crtn.fini");
143 }
144
145 /* End the here document containing the .fini epilogue code.
146    Finally, put the remainder of the generated assembly into crtcommon.tmp.  */
147 asm ("\nEOF.crtn.fini\
148 \n\
149 cat > crtcommon.tmp <<\\EOF_common");