* sysdeps/ia64/elf/initfini.c [HAVE_INITFINI_ARRAY]
[platform/upstream/glibc.git] / sysdeps / ia64 / elf / initfini.c
1 /* Special .init and .fini section support for ia64.
2    Copyright (C) 2000, 2002 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 Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the 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    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
19
20 /* This file is compiled into assembly code which is then munged by a sed
21    script into two files: crti.s and crtn.s.
22
23    * crti.s puts a function prologue at the beginning of the
24    .init and .fini sections and defines global symbols for
25    those addresses, so they can be called as functions.
26
27    * crtn.s puts the corresponding function epilogues
28    in the .init and .fini sections. */
29
30 __asm__ ("\n\n"
31 "#include \"defs.h\"\n"
32 "\n"
33 "/*@HEADER_ENDS*/\n"
34 "\n"
35 "/*@_init_PROLOG_BEGINS*/\n");
36
37 #ifdef HAVE_INITFINI_ARRAY
38
39 /* If we have working .init_array support, we want to keep the .init
40    section empty (apart from the mandatory prologue/epilogue.  This
41    ensures that the default unwind conventions (return-pointer in b0,
42    frame state in ar.pfs, etc.)  will do the Right Thing.  To ensure
43    an empty .init section, we register gmon_initializer() via the
44    .init_array.
45
46         --davidm 02/10/29 */
47
48 static void
49 gmon_initializer (void)
50 {
51   extern void weak_function __gmon_start__ (void);
52
53   if (__gmon_start__)
54     (*__gmon_start__)();
55 }
56
57 __asm__ (".section .init_array, \"aw\"\n"
58          "\tdata8 @fptr(gmon_initializer)\n");
59
60 #endif
61
62 __asm__ (".section .init\n"
63 "       .align 16\n"
64 "       .global _init#\n"
65 "       .proc _init#\n"
66 "_init:\n"
67 "       alloc r34 = ar.pfs, 0, 3, 0, 0\n"
68 "       mov r32 = r12\n"
69 "       mov r33 = b0\n"
70 "       adds r12 = -16, r12\n"
71 #ifdef HAVE_INITFINI_ARRAY
72  "      ;;\n"           /* see gmon_initializer() below */
73 #else
74 "       .weak   __gmon_start__#\n"
75 "       addl r14 = @ltoff(@fptr(__gmon_start__#)), gp\n"
76 "       ;;\n"
77 "       ld8 r15 = [r14]\n"
78 "       ;;\n"
79 "       cmp.eq p6, p7 = 0, r15\n"
80 "       (p6) br.cond.dptk .L5\n"
81 "\n"
82 "/* we could use r35 to save gp, but we use the stack since that's what\n"
83 " * all the other init routines will do --davidm 00/04/05 */\n"
84 "       st8 [r12] = gp, -16\n"
85 "       br.call.sptk.many b0 = __gmon_start__# ;;\n"
86 "       adds r12 = 16, r12\n"
87 "       ;;\n"
88 "       ld8 gp = [r12]\n"
89 "       ;;\n"
90 ".L5:\n"
91 #endif
92 "       .align 16\n"
93 "       .endp _init#\n"
94 "\n"
95 "/*@_init_PROLOG_ENDS*/\n"
96 "\n"
97 "/*@_init_EPILOG_BEGINS*/\n"
98 "       .section .init\n"
99 "       .regstk 0,2,0,0\n"
100 "       mov r12 = r32\n"
101 "       mov ar.pfs = r34\n"
102 "       mov b0 = r33\n"
103 "       br.ret.sptk.many b0\n"
104 "       .endp _init#\n"
105 "/*@_init_EPILOG_ENDS*/\n"
106 "\n"
107 "/*@_fini_PROLOG_BEGINS*/\n"
108 "       .section .fini\n"
109 "       .align 16\n"
110 "       .global _fini#\n"
111 "       .proc _fini#\n"
112 "_fini:\n"
113 "       alloc r34 = ar.pfs, 0, 3, 0, 0\n"
114 "       mov r32 = r12\n"
115 "       mov r33 = b0\n"
116 "       adds r12 = -16, r12\n"
117 "       ;;\n"
118 "       .align 16\n"
119 "       .endp _fini#\n"
120 "\n"
121 "/*@_fini_PROLOG_ENDS*/\n"
122 "       br.call.sptk.many b0 = i_am_not_a_leaf# ;;\n"
123 "       ;;\n"
124 "\n"
125 "/*@_fini_EPILOG_BEGINS*/\n"
126 "       .section .fini\n"
127 "       mov r12 = r32\n"
128 "       mov ar.pfs = r34\n"
129 "       mov b0 = r33\n"
130 "       br.ret.sptk.many b0\n"
131 "       .endp _fini#\n"
132 "\n"
133 "/*@_fini_EPILOG_ENDS*/\n"
134 "\n"
135 "/*@TRAILER_BEGINS*/\n"
136 );