|
|
1.1 ! root 1: ! crt1.s for Solaris 2, x86 ! 2: ! 3: ! Copyright (C) 1993 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 2, or (at your option) any ! 9: ! later version. ! 10: ! ! 11: ! In addition to the permissions in the GNU General Public License, the ! 12: ! Free Software Foundation gives you unlimited permission to link the ! 13: ! compiled version of this file with other programs, and to distribute ! 14: ! those programs without any restriction coming from the use of this ! 15: ! file. (The General Public License restrictions do apply in other ! 16: ! respects; for example, they cover modification of the file, and ! 17: ! distribution when not linked into another program.) ! 18: ! ! 19: ! This file is distributed in the hope that it will be useful, but ! 20: ! WITHOUT ANY WARRANTY; without even the implied warranty of ! 21: ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ! 22: ! General Public License for more details. ! 23: ! ! 24: ! You should have received a copy of the GNU General Public License ! 25: ! along with this program; see the file COPYING. If not, write to ! 26: ! the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. ! 27: ! ! 28: ! As a special exception, if you link this library with files ! 29: ! compiled with GCC to produce an executable, this does not cause ! 30: ! the resulting executable to be covered by the GNU General Public License. ! 31: ! This exception does not however invalidate any other reasons why ! 32: ! the executable file might be covered by the GNU General Public License. ! 33: ! ! 34: ! 35: ! This file takes control of the process from the kernel, as specified ! 36: ! in section 3 of the System V Application Binary Interface, Intel386 ! 37: ! Processor Supplement. It has been constructed from information obtained ! 38: ! from the ABI, information obtained from single stepping existing ! 39: ! Solaris executables through their startup code with gdb, and from ! 40: ! information obtained by single stepping executables on other i386 SVR4 ! 41: ! implementations. This file is the first thing linked into any executable. ! 42: ! 43: .file "crt1.s" ! 44: .ident "GNU C crt1.s" ! 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: ! Compute the address of the environment vector on the stack and load ! 98: ! it into the global variable _environ. Currently argc is at 8 off ! 99: ! the frame pointer. Fetch the argument count into %eax, scale by the ! 100: ! size of each arg (4 bytes) and compute the address of the environment ! 101: ! vector which is 16 bytes (the two zero words we pushed, plus argc, ! 102: ! plus the null word terminating the arg vector) further up the stack, ! 103: ! off the frame pointer (whew!). ! 104: ! 105: movl 8(%ebp),%eax ! 106: leal 16(%ebp,%eax,4),%edx ! 107: movl %edx,_environ ! 108: ! 109: ! Push the environment vector pointer, the argument vector pointer, ! 110: ! and the argument count on to the stack to set up the arguments ! 111: ! for _init(), _fpstart(), and main(). Note that the environment ! 112: ! vector pointer and the arg count were previously loaded into ! 113: ! %edx and %eax respectively. The only new value we need to compute ! 114: ! is the argument vector pointer, which is at a fixed address off ! 115: ! the initial frame pointer. ! 116: ! 117: pushl %edx ! 118: leal 12(%ebp),%edx ! 119: pushl %edx ! 120: pushl %eax ! 121: ! 122: ! Call _init(argc, argv, environ), _fpstart(argc, argv, environ), and ! 123: ! main(argc, argv, environ). ! 124: ! 125: call _init ! 126: call __fpstart ! 127: call main ! 128: ! 129: ! Pop the argc, argv, and environ arguments off the stack, push the ! 130: ! value returned from main(), and call exit(). ! 131: ! 132: addl $12,%esp ! 133: pushl %eax ! 134: call exit ! 135: ! 136: ! An inline equivalent of _exit, as specified in Figure 3-26 of the ABI. ! 137: ! 138: pushl $0x0 ! 139: movl $0x1,%eax ! 140: lcall $7,$0 ! 141: ! 142: ! If all else fails, just try a halt! ! 143: ! 144: hlt ! 145: .type _start,@function ! 146: .size _start,.-_start ! 147: ! 148: ! A dummy profiling support routine for non-profiling executables, ! 149: ! in case we link in some objects that have been compiled for profiling. ! 150: ! 151: .globl _mcount ! 152: _mcount: ! 153: ret ! 154: .type _mcount,@function ! 155: .size _mcount,.-_mcount
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.