]> git.ipfire.org Git - thirdparty/gcc.git/blob - libgcc/config/i386/sol2-c1.S
Update copyright years.
[thirdparty/gcc.git] / libgcc / config / i386 / sol2-c1.S
1 /* crt1.s for Solaris 2, x86
2
3 Copyright (C) 1993-2021 Free Software Foundation, Inc.
4 Written By Fred Fish, Nov 1992
5
6 This file is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 3, or (at your option) any
9 later version.
10
11 This file is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 Under Section 7 of GPL version 3, you are granted additional
17 permissions described in the GCC Runtime Library Exception, version
18 3.1, as published by the Free Software Foundation.
19
20 You should have received a copy of the GNU General Public License and
21 a copy of the GCC Runtime Library Exception along with this program;
22 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 <http://www.gnu.org/licenses/>. */
24
25
26 /* This file takes control of the process from the kernel, as specified
27 in section 3 of the System V Application Binary Interface, Intel386
28 Processor Supplement. It has been constructed from information obtained
29 from the ABI, information obtained from single stepping existing
30 Solaris executables through their startup code with gdb, and from
31 information obtained by single stepping executables on other i386 SVR4
32 implementations. This file is the first thing linked into any
33 executable. */
34
35 #ifndef GCRT1
36 .ident "GNU C crt1.s"
37 #define CLEANUP _cleanup
38 #else
39 /* This is a modified crt1.s by J.W.Hawtin <oolon@ankh.org> 15/8/96,
40 to allow program profiling, by calling monstartup on entry and _mcleanup
41 on exit. */
42 .ident "GNU C gcrt1.s"
43 #define CLEANUP _mcleanup
44 #endif
45 .weak _cleanup
46 .weak _DYNAMIC
47 .text
48
49 /* Start creating the initial frame by pushing a NULL value for the return
50 address of the initial frame, and mark the end of the stack frame chain
51 (the innermost stack frame) with a NULL value, per page 3-32 of the ABI.
52 Initialize the first stack frame pointer in %ebp (the contents of which
53 are unspecified at process initialization). */
54
55 .globl _start
56 _start:
57 pushl $0x0
58 pushl $0x0
59 movl %esp,%ebp
60
61 /* As specified per page 3-32 of the ABI, %edx contains a function
62 pointer that should be registered with atexit(), for proper
63 shared object termination. Just push it onto the stack for now
64 to preserve it. We want to register _cleanup() first. */
65
66 pushl %edx
67
68 /* Check to see if there is an _cleanup() function linked in, and if
69 so, register it with atexit() as the last thing to be run by
70 atexit(). */
71
72 movl $CLEANUP,%eax
73 testl %eax,%eax
74 je .L1
75 pushl $CLEANUP
76 call atexit
77 addl $0x4,%esp
78 .L1:
79
80 /* Now check to see if we have an _DYNAMIC table, and if so then
81 we need to register the function pointer previously in %edx, but
82 now conveniently saved on the stack as the argument to pass to
83 atexit(). */
84
85 movl $_DYNAMIC,%eax
86 testl %eax,%eax
87 je .L2
88 call atexit
89 .L2:
90
91 /* Register _fini() with atexit(). We will take care of calling _init()
92 directly. */
93
94 pushl $_fini
95 call atexit
96
97 #ifdef GCRT1
98 /* Start profiling. */
99
100 pushl %ebp
101 movl %esp,%ebp
102 pushl $_etext
103 pushl $_start
104 call monstartup
105 addl $8,%esp
106 popl %ebp
107 #endif
108
109 /* Compute the address of the environment vector on the stack and load
110 it into the global variable _environ. Currently argc is at 8 off
111 the frame pointer. Fetch the argument count into %eax, scale by the
112 size of each arg (4 bytes) and compute the address of the environment
113 vector which is 16 bytes (the two zero words we pushed, plus argc,
114 plus the null word terminating the arg vector) further up the stack,
115 off the frame pointer (whew!). */
116
117 movl 8(%ebp),%eax
118 leal 16(%ebp,%eax,4),%edx
119 movl %edx,_environ
120
121 /* Push the environment vector pointer, the argument vector pointer,
122 and the argument count on to the stack to set up the arguments
123 for _init(), _fpstart(), and main(). Note that the environment
124 vector pointer and the arg count were previously loaded into
125 %edx and %eax respectively. The only new value we need to compute
126 is the argument vector pointer, which is at a fixed address off
127 the initial frame pointer. */
128
129 /* Make sure the stack is properly aligned. */
130 andl $0xfffffff0,%esp
131 subl $4,%esp
132
133 pushl %edx
134 leal 12(%ebp),%edx
135 pushl %edx
136 pushl %eax
137
138 /* Call _init(argc, argv, environ), _fpstart(argc, argv, environ), and
139 main(argc, argv, environ). */
140
141 call _init
142 call __fpstart
143 call main
144
145 /* Pop the argc, argv, and environ arguments off the stack, push the
146 value returned from main(), and call exit(). */
147
148 addl $12,%esp
149 pushl %eax
150 call exit
151
152 /* An inline equivalent of _exit, as specified in Figure 3-26 of the ABI. */
153
154 pushl $0x0
155 movl $0x1,%eax
156 lcall $7,$0
157
158 /* If all else fails, just try a halt! */
159
160 hlt
161 .type _start,@function
162 .size _start,.-_start
163
164 #ifndef GCRT1
165 /* A dummy profiling support routine for non-profiling executables,
166 in case we link in some objects that have been compiled for profiling. */
167
168 .weak _mcount
169 _mcount:
170 ret
171 .type _mcount,@function
172 .size _mcount,.-_mcount
173 #endif