1{ 2 This file is part of the Free Pascal run time library. 3 Copyright (c) 2005 by Michael Van Canneyt, Peter Vreman, 4 & Daniel Mantione, members of the Free Pascal development team. 5 6 See the file COPYING.FPC, included in this distribution, 7 for details about the copyright. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 13 **********************************************************************} 14 15{ 16 Linux ELF startup code for Free Pascal 17 18 19 Stack layout at program start: 20 21 nil 22 envn 23 .... 24 .... ENVIRONMENT VARIABLES 25 env1 26 env0 27 nil 28 argn 29 .... 30 .... COMMAND LINE OPTIONS 31 arg1 32 arg0 33 argc <--- esp 34} 35 36var 37 libc_environ: pchar; external name '__environ'; 38 libc_fpu_control: word; external name '__fpu_control'; 39 libc_init_proc: procedure; external name '_init'; 40 libc_fini_proc: procedure; external name '_fini'; 41 42procedure libc_atexit; external name '__libc_atexit'; 43procedure libc_exit; external name '__libc_exit'; 44procedure libc_init; external name '__libc_init'; 45procedure libc_setfpucw; external name '__setfpucw'; 46procedure libc_start_main; external name '__libc_start_main'; 47 48Procedure fpc_geteipasebx;[external name 'fpc_geteipasebx']; 49 50{****************************************************************************** 51 C library start/halt 52 ******************************************************************************} 53{$asmmode ATT} 54 55procedure _FPC_libc_start; assembler; nostackframe; public name '_start'; 56asm 57 { First locate the start of the environment variables } 58 popl %ecx { Get argc in ecx } 59 60 {$ifdef FPC_PIC} 61 movl %esp,%ebp { Points to the arguments } 62 movl %ecx,%esi 63 {$else FPC_PIC} 64 movl %esp,%ebx { Points to the arguments } 65 {$endif FPC_PIC} 66 67 leal 4(%esp,%ecx,4),%eax { The start of the environment is: esp+4*eax+8 } 68 andl $0xfffffff8,%esp { Align stack } 69 70 {$ifdef FPC_PIC} 71 pushl %ecx 72 call fpc_geteipasebx 73 addl $_GLOBAL_OFFSET_TABLE_,%ebx 74 movl operatingsystem_parameter_envp@GOT(%ebx),%ecx 75 movl %eax,(%ecx) 76 movl libc_environ@GOT(%ebx),%ecx 77 movl %eax,(%ecx) 78 79 pushl %eax 80 movl operatingsystem_parameter_argc@GOT(%ebx),%ecx 81 movl %esi,%eax 82 movl %eax,(%ecx) 83 movl operatingsystem_parameter_argv@GOT(%ebx),%ecx 84 movl %ebp,%eax 85 movl %eax,(%ecx) 86 popl %eax 87 88 popl %ecx 89 movl %ebp,%ebx 90 {$else FPC_PIC} 91 movl %eax,operatingsystem_parameter_envp { Move the environment pointer } 92 movl %ecx,operatingsystem_parameter_argc { Move the argument counter } 93 movl %ebx,operatingsystem_parameter_argv { Move the argument pointer } 94 movl %eax,libc_environ { libc environ } 95 {$endif FPC_PIC} 96 97 98 pushl %eax 99 pushl %ebx 100 pushl %ecx 101 102 call libc_init { init libc } 103 104 {$ifdef FPC_PIC} 105 pushl %ecx 106 pushl %ebx 107 call fpc_geteipasebx 108 addl $_GLOBAL_OFFSET_TABLE_,%ebx 109 movl libc_init_proc@GOT(%ebx),%ecx 110 movl (%ecx),%edi 111 popl %ebx 112 popl %ecx 113 {$else FPC_PIC} 114 movzwl libc_fpu_control,%eax 115 {$endif FPC_PIC} 116 117 118 pushl %eax 119 call libc_setfpucw 120 popl %eax 121 pushl $libc_fini_proc 122 call libc_atexit 123 popl %eax 124 125 {$ifdef FPC_PIC} 126 call *%edi 127 {$else FPC_PIC} 128 call libc_init_proc 129 {$endif FPC_PIC} 130 131 popl %eax 132 popl %eax 133 134 { Save initial stackpointer } 135 {$ifdef FPC_PIC} 136 pushl %ecx 137 pushl %ebx 138 call fpc_geteipasebx 139 addl $_GLOBAL_OFFSET_TABLE_,%ebx 140 movl initialstkptr@GOT(%ebx),%ecx 141 movl %esp,(%ecx) 142 popl %ebx 143 popl %ecx 144 {$else FPC_PIC} 145 movl %esp,initialstkptr 146 {$endif FPC_PIC} 147 148 xorl %ebp,%ebp 149 call PASCALMAIN { start the program } 150end; 151 152procedure _FPC_libc_haltproc(e: longint); cdecl; assembler; public name '_haltproc'; 153asm 154.Lhaltproc: 155 pushl e 156 call libc_exit 157 xorl %eax,%eax 158 incl %eax { eax=1, exit call } 159 movl e,%ebx 160 int $0x80 161 jmp .Lhaltproc 162end; 163 164