si_c21.inc 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  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. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {
  12. Linux ELF startup code for Free Pascal
  13. Stack layout at program start:
  14. nil
  15. envn
  16. ....
  17. .... ENVIRONMENT VARIABLES
  18. env1
  19. env0
  20. nil
  21. argn
  22. ....
  23. .... COMMAND LINE OPTIONS
  24. arg1
  25. arg0
  26. argc <--- esp
  27. }
  28. {$asmmode att}
  29. var
  30. dlexitproc: pointer; { atexit from loader }
  31. procedure libc_start_main; external name '__libc_start_main';
  32. procedure PASCALMAIN; external name 'PASCALMAIN';
  33. { Some helpers }
  34. procedure _init_fini_dummy; compilerproc; nostackframe; assembler;
  35. asm
  36. ret
  37. end;
  38. {******************************************************************************
  39. glibc 2.1 lib + profiling start/halt
  40. ******************************************************************************}
  41. procedure _FPC_libc21_start; assembler; nostackframe; public name '_start';
  42. asm
  43. xorl %ebp,%ebp
  44. { First locate the start of the environment variables }
  45. popl %ecx { Get argc in ecx }
  46. movl %esp,%ebx { Esp now points to the arguments }
  47. leal 4(%esp,%ecx,4),%eax { The start of the environment is: esp+4*eax+4 }
  48. andl $0xfffffff8,%esp { Align stack }
  49. {$ifdef FPC_PIC}
  50. pushl %edx
  51. pushl %ebx
  52. pushl %ecx
  53. call .Lpiclab
  54. .Lpiclab:
  55. popl %ebx
  56. addl $_GLOBAL_OFFSET_TABLE_,%ebx
  57. movl dlexitproc@GOT(%ebx),%ecx
  58. movl %edx,(%ecx)
  59. movl operatingsystem_parameter_envp@GOT(%ebx),%ecx
  60. movl %eax,(%ecx)
  61. movl operatingsystem_parameter_argc@GOT(%ebx),%edx
  62. popl %ecx
  63. movl %ecx,(%edx)
  64. movl operatingsystem_parameter_argv@GOT(%ebx),%edx
  65. popl %ebx
  66. movl %ebx,(%edx)
  67. popl %edx
  68. {$else FPC_PIC}
  69. movl %edx, dlexitproc
  70. movl %eax,operatingsystem_parameter_envp
  71. movl %ecx,operatingsystem_parameter_argc
  72. movl %ebx,operatingsystem_parameter_argv
  73. {$endif FPC_PIC}
  74. { Save initial stackpointer }
  75. {$ifdef FPC_PIC}
  76. pushl %ebx
  77. call .Lpiclab2
  78. .Lpiclab2:
  79. popl %ebx
  80. addl $_GLOBAL_OFFSET_TABLE_,%ebx
  81. movl initialstkptr@GOT(%ebx),%ebx
  82. movl %esp,(%ebx)
  83. popl %ebx
  84. {$else FPC_PIC}
  85. movl %esp,initialstkptr
  86. {$endif FPC_PIC}
  87. { int __libc_start_main(
  88. int *(main) (int, char * *, char * *),
  89. int argc,
  90. char * * ubp_av,
  91. void (*init) (void),
  92. void (*fini) (void),
  93. void (*rtld_fini) (void),
  94. void (* stack_end)); }
  95. pushl %ebp { padding }
  96. pushl %esp { stack_end }
  97. pushl %edx { function to be registered with
  98. atexit(), passed by loader }
  99. pushl $_init_fini_dummy
  100. pushl $_init_fini_dummy
  101. pushl %ebx { Push second argument: argv. }
  102. pushl %ecx { Push first argument: argc. }
  103. pushl $PASCALMAIN
  104. call libc_start_main
  105. hlt
  106. end;
  107. procedure _FPC_libc21_haltproc; assembler; nostackframe; public name '_haltproc';
  108. asm
  109. .Lhaltproc:
  110. {$ifdef FPC_PIC}
  111. call .Lpiclab
  112. .Lpiclab:
  113. popl %ebx
  114. addl $_GLOBAL_OFFSET_TABLE_,%ebx
  115. movl dlexitproc@GOT(%ebx),%eax
  116. movl (%eax),%eax
  117. {$else FPC_PIC}
  118. movl dlexitproc,%eax
  119. {$endif FPC_PIC}
  120. testl %eax,%eax
  121. je .Lnodlexitproc
  122. call *%eax
  123. .Lnodlexitproc:
  124. movl syscall_nr_exit_group,%eax
  125. {$ifdef FPC_PIC}
  126. call .Lpiclab2
  127. .Lpiclab2:
  128. popl %ebx
  129. addl $_GLOBAL_OFFSET_TABLE_,%ebx
  130. movl ExitCode@GOT(%ebx),%ebx
  131. {$if sizeof(ExitCode)=2}
  132. movzwl (%ebx),%ebx
  133. {$else}
  134. mov (%ebx),%ebx
  135. {$endif}
  136. {$else FPC_PIC}
  137. {$if sizeof(ExitCode)=2}
  138. movzwl ExitCode,%ebx
  139. {$else}
  140. mov ExitCode,%ebx
  141. {$endif}
  142. {$endif FPC_PIC}
  143. int $0x80
  144. movl syscall_nr_exit,%eax
  145. {$ifdef FPC_PIC}
  146. call .Lpiclab3
  147. .Lpiclab3:
  148. popl %ebx
  149. addl $_GLOBAL_OFFSET_TABLE_,%ebx
  150. movl ExitCode@GOT(%ebx),%ebx
  151. {$if sizeof(ExitCode)=2}
  152. movzwl (%ebx),%ebx
  153. {$else}
  154. mov (%ebx),%ebx
  155. {$endif}
  156. {$else FPC_PIC}
  157. {$if sizeof(ExitCode)=2}
  158. movzwl ExitCode,%ebx
  159. {$else}
  160. mov ExitCode,%ebx
  161. {$endif}
  162. {$endif FPC_PIC}
  163. int $0x80
  164. jmp .Lhaltproc
  165. end;