sol2-gc1.asm revision 169689
1178739Sgonzo! gcrt1.s for Solaris 2, x86 2178739Sgonzo 3178739Sgonzo! Copyright (C) 1993 Free Software Foundation, Inc. 4178739Sgonzo! Written By Fred Fish, Nov 1992 5178739Sgonzo! 6178739Sgonzo! This file is free software; you can redistribute it and/or modify it 7178739Sgonzo! under the terms of the GNU General Public License as published by the 8178739Sgonzo! Free Software Foundation; either version 2, or (at your option) any 9178739Sgonzo! later version. 10178739Sgonzo! 11178739Sgonzo! In addition to the permissions in the GNU General Public License, the 12178739Sgonzo! Free Software Foundation gives you unlimited permission to link the 13178739Sgonzo! compiled version of this file with other programs, and to distribute 14178739Sgonzo! those programs without any restriction coming from the use of this 15178739Sgonzo! file. (The General Public License restrictions do apply in other 16178739Sgonzo! respects; for example, they cover modification of the file, and 17178739Sgonzo! distribution when not linked into another program.) 18178739Sgonzo! 19178739Sgonzo! This file is distributed in the hope that it will be useful, but 20178739Sgonzo! WITHOUT ANY WARRANTY; without even the implied warranty of 21178739Sgonzo! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22178739Sgonzo! General Public License for more details. 23178739Sgonzo! 24178739Sgonzo! You should have received a copy of the GNU General Public License 25178739Sgonzo! along with this program; see the file COPYING. If not, write to 26178739Sgonzo! the Free Software Foundation, 51 Franklin Street, Fifth Floor, 27178739Sgonzo! Boston, MA 02110-1301, USA. 28178739Sgonzo! 29178739Sgonzo! As a special exception, if you link this library with files 30178739Sgonzo! compiled with GCC to produce an executable, this does not cause 31178739Sgonzo! the resulting executable to be covered by the GNU General Public License. 32178739Sgonzo! This exception does not however invalidate any other reasons why 33178739Sgonzo! the executable file might be covered by the GNU General Public License. 34178739Sgonzo! 35178739Sgonzo 36178739Sgonzo! This file takes control of the process from the kernel, as specified 37178739Sgonzo! in section 3 of the System V Application Binary Interface, Intel386 38178739Sgonzo! Processor Supplement. It has been constructed from information obtained 39178739Sgonzo! from the ABI, information obtained from single stepping existing 40178739Sgonzo! Solaris executables through their startup code with gdb, and from 41178739Sgonzo! information obtained by single stepping executables on other i386 SVR4 42178739Sgonzo! implementations. This file is the first thing linked into any executable. 43178739Sgonzo 44178739Sgonzo! This is a modified crt1.s by J.W.Hawtin <oolon@ankh.org> 15/8/96, 45178739Sgonzo! to allow program profiling, by calling monstartup on entry and _mcleanup 46232832Skib! on exit 47178739Sgonzo 48178739Sgonzo .file "gcrt1.s" 49178739Sgonzo .ident "GNU C gcrt1.s" 50178739Sgonzo .weak _DYNAMIC 51178739Sgonzo .text 52178739Sgonzo 53178739Sgonzo! Start creating the initial frame by pushing a NULL value for the return 54178739Sgonzo! address of the initial frame, and mark the end of the stack frame chain 55178739Sgonzo! (the innermost stack frame) with a NULL value, per page 3-32 of the ABI. 56178739Sgonzo! Initialize the first stack frame pointer in %ebp (the contents of which 57178739Sgonzo! are unspecified at process initialization). 58204756Suqs 59204756Suqs .globl _start 60178739Sgonzo_start: 61178739Sgonzo pushl $0x0 62178739Sgonzo pushl $0x0 63178739Sgonzo movl %esp,%ebp 64204757Suqs 65204757Suqs! As specified per page 3-32 of the ABI, %edx contains a function 66178739Sgonzo! pointer that should be registered with atexit(), for proper 67178739Sgonzo! shared object termination. Just push it onto the stack for now 68178739Sgonzo! to preserve it. We want to register _cleanup() first. 69178739Sgonzo 70178739Sgonzo pushl %edx 71178739Sgonzo 72178739Sgonzo! Check to see if there is an _cleanup() function linked in, and if 73178739Sgonzo! so, register it with atexit() as the last thing to be run by 74245133Skib! atexit(). 75178739Sgonzo 76178739Sgonzo movl $_mcleanup,%eax 77178739Sgonzo testl %eax,%eax 78232580Sgonzo je .L1 79232580Sgonzo pushl $_mcleanup 80232580Sgonzo call atexit 81178739Sgonzo addl $0x4,%esp 82178739Sgonzo.L1: 83178739Sgonzo 84178739Sgonzo! Now check to see if we have an _DYNAMIC table, and if so then 85232832Skib! we need to register the function pointer previously in %edx, but 86232832Skib! now conveniently saved on the stack as the argument to pass to 87232832Skib! atexit(). 88178739Sgonzo 89178739Sgonzo movl $_DYNAMIC,%eax 90178739Sgonzo testl %eax,%eax 91178739Sgonzo je .L2 92178739Sgonzo call atexit 93178739Sgonzo.L2: 94178739Sgonzo 95! Register _fini() with atexit(). We will take care of calling _init() 96! directly. 97 98 pushl $_fini 99 call atexit 100 101! Start profiling 102 103 pushl %ebp 104 movl %esp,%ebp 105 pushl $_etext 106 pushl $_start 107 call monstartup 108 addl $8,%esp 109 popl %ebp 110 111! Compute the address of the environment vector on the stack and load 112! it into the global variable _environ. Currently argc is at 8 off 113! the frame pointer. Fetch the argument count into %eax, scale by the 114! size of each arg (4 bytes) and compute the address of the environment 115! vector which is 16 bytes (the two zero words we pushed, plus argc, 116! plus the null word terminating the arg vector) further up the stack, 117! off the frame pointer (whew!). 118 119 movl 8(%ebp),%eax 120 leal 16(%ebp,%eax,4),%edx 121 movl %edx,_environ 122 123! Push the environment vector pointer, the argument vector pointer, 124! and the argument count on to the stack to set up the arguments 125! for _init(), _fpstart(), and main(). Note that the environment 126! vector pointer and the arg count were previously loaded into 127! %edx and %eax respectively. The only new value we need to compute 128! is the argument vector pointer, which is at a fixed address off 129! the initial frame pointer. 130 131! 132! Make sure the stack is properly aligned. 133! 134 andl $0xfffffff0,%esp 135 subl $4,%esp 136 137 pushl %edx 138 leal 12(%ebp),%edx 139 pushl %edx 140 pushl %eax 141 142! Call _init(argc, argv, environ), _fpstart(argc, argv, environ), and 143! main(argc, argv, environ). 144 145 call _init 146 call __fpstart 147 call main 148 149! Pop the argc, argv, and environ arguments off the stack, push the 150! value returned from main(), and call exit(). 151 152 addl $12,%esp 153 pushl %eax 154 call exit 155 156! An inline equivalent of _exit, as specified in Figure 3-26 of the ABI. 157 158 pushl $0x0 159 movl $0x1,%eax 160 lcall $7,$0 161 162! If all else fails, just try a halt! 163 164 hlt 165 .type _start,@function 166 .size _start,.-_start 167