si_c21g.inc 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  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. {
  29. This file is part of the Free Pascal run time library.
  30. Copyright (c) 2005 by Michael Van Canneyt, Peter Vreman,
  31. & Daniel Mantione, members of the Free Pascal development team.
  32. See the file COPYING.FPC, included in this distribution,
  33. for details about the copyright.
  34. This program is distributed in the hope that it will be useful,
  35. but WITHOUT ANY WARRANTY; without even the implied warranty of
  36. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  37. **********************************************************************}
  38. {
  39. Linux ELF startup code for Free Pascal
  40. Stack layout at program start:
  41. nil
  42. envn
  43. ....
  44. .... ENVIRONMENT VARIABLES
  45. env1
  46. env0
  47. nil
  48. argn
  49. ....
  50. .... COMMAND LINE OPTIONS
  51. arg1
  52. arg0
  53. argc <--- esp
  54. }
  55. {$asmmode att}
  56. { Some helpers }
  57. {$ifdef FPC_PIC}
  58. function fpc0geteipasebx : pointer; compilerproc; nostackframe; assembler;
  59. asm
  60. movl (%esp),%ebx
  61. ret
  62. end;
  63. {$endif FPC_PIC}
  64. procedure _init_fini_dummy; compilerproc; nostackframe; assembler;
  65. asm
  66. ret
  67. end;
  68. procedure gmon_mcleanup; cdecl; external name '_mcleanup';
  69. procedure gmon_monstartup (main,etext : pointer);cdecl;external name 'monstartup';
  70. procedure libc_start_main; external name '__libc_start_main';
  71. procedure PASCALMAIN; external name 'PASCALMAIN';
  72. var
  73. dlexitproc: pointer; { atexit from loader }
  74. gmon_start : record end;external name 'PASCALMAIN';
  75. gmon_etext : record end;external name '_etext';
  76. gmon_monstarted: longint = 0;
  77. {******************************************************************************
  78. Process start/halt
  79. ******************************************************************************}
  80. procedure _FPC_libc21_gprof_gmon_start; public name '_FPC_libc21_gprof_gmon_start';
  81. begin
  82. if gmon_monstarted=0 then
  83. begin
  84. inc(gmon_monstarted);
  85. gmon_monstartup(@gmon_start,@gmon_etext);
  86. end;
  87. PASCALMAIN;
  88. end;
  89. procedure _FPC_libc21_gprof_start; assembler; nostackframe; public name '_start';
  90. asm
  91. xorl %ebp,%ebp
  92. { First locate the start of the environment variables }
  93. popl %ecx { Get argc in ecx }
  94. movl %esp,%ebx { Esp now points to the arguments }
  95. leal 4(%esp,%ecx,4),%eax { The start of the environment is: esp+4*eax+4 }
  96. andl $0xfffffff8,%esp { Align stack }
  97. {$ifdef FPC_PIC}
  98. pushl %edx
  99. pushl %ebx
  100. pushl %ecx
  101. call fpc0geteipasebx
  102. addl $_GLOBAL_OFFSET_TABLE_,%ebx
  103. movl dlexitproc@GOT(%ebx),%ecx
  104. movl %edx,(%ecx)
  105. movl operatingsystem_parameter_envp@GOT(%ebx),%ecx
  106. movl %eax,(%ecx)
  107. movl operatingsystem_parameter_argc@GOT(%ebx),%edx
  108. popl %ecx
  109. movl %ecx,(%edx)
  110. movl operatingsystem_parameter_argv@GOT(%ebx),%edx
  111. popl %ebx
  112. movl %ebx,(%edx)
  113. popl %edx
  114. {$else FPC_PIC}
  115. movl %edx, dlexitproc
  116. movl %eax,operatingsystem_parameter_envp
  117. movl %ecx,operatingsystem_parameter_argc
  118. movl %ebx,operatingsystem_parameter_argv
  119. {$endif FPC_PIC}
  120. { Save initial stackpointer }
  121. {$ifdef FPC_PIC}
  122. pushl %ebx
  123. call fpc0geteipasebx
  124. addl $_GLOBAL_OFFSET_TABLE_,%ebx
  125. movl initialstkptr@GOT(%ebx),%ebx
  126. movl %esp,(%ebx)
  127. popl %ebx
  128. {$else FPC_PIC}
  129. movl %esp,initialstkptr
  130. {$endif FPC_PIC}
  131. { int __libc_start_main(
  132. int *(main) (int, char * *, char * *),
  133. int argc,
  134. char * * ubp_av,
  135. void (*init) (void),
  136. void (*fini) (void),
  137. void (*rtld_fini) (void),
  138. void (* stack_end)); }
  139. pushl %ebp { padding }
  140. pushl %esp { stack_end }
  141. pushl %edx { function to be registered with
  142. atexit(), passed by loader }
  143. pushl $_init_fini_dummy
  144. pushl $_init_fini_dummy
  145. pushl %ebx { Push second argument: argv. }
  146. pushl %ecx { Push first argument: argc. }
  147. pushl $_FPC_libc21_gprof_gmon_start
  148. call libc_start_main
  149. hlt
  150. end;
  151. procedure _FPC_libc21_gprof_haltproc(e:longint);cdecl;public name '_haltproc';
  152. begin
  153. if gmon_monstarted=1 then
  154. begin
  155. dec(gmon_monstarted);
  156. gmon_mcleanup;
  157. end;
  158. asm
  159. .Lhaltproc:
  160. {$ifdef FPC_PIC}
  161. call fpc0geteipasebx
  162. addl $_GLOBAL_OFFSET_TABLE_,%ebx
  163. movl dlexitproc@GOT(%ebx),%eax
  164. movl (%eax),%eax
  165. {$else FPC_PIC}
  166. movl dlexitproc,%eax
  167. {$endif FPC_PIC}
  168. testl %eax,%eax
  169. je .Lnodlexitproc
  170. call *%eax
  171. .Lnodlexitproc:
  172. movl syscall_nr_exit_group,%eax
  173. {$ifdef FPC_PIC}
  174. call fpc0geteipasebx
  175. addl $_GLOBAL_OFFSET_TABLE_,%ebx
  176. movl ExitCode@GOT(%ebx),%ebx
  177. {$if sizeof(ExitCode)=2}
  178. movzwl (%ebx),%ebx
  179. {$else}
  180. mov (%ebx),%ebx
  181. {$endif}
  182. {$else FPC_PIC}
  183. {$if sizeof(ExitCode)=2}
  184. movzwl ExitCode,%ebx
  185. {$else}
  186. mov ExitCode,%ebx
  187. {$endif}
  188. {$endif FPC_PIC}
  189. int $0x80
  190. movl syscall_nr_exit,%eax
  191. {$ifdef FPC_PIC}
  192. call fpc0geteipasebx
  193. addl $_GLOBAL_OFFSET_TABLE_,%ebx
  194. movl ExitCode@GOT(%ebx),%ebx
  195. {$if sizeof(ExitCode)=2}
  196. movzwl (%ebx),%ebx
  197. {$else}
  198. mov (%ebx),%ebx
  199. {$endif}
  200. {$else FPC_PIC}
  201. {$if sizeof(ExitCode)=2}
  202. movzwl ExitCode,%ebx
  203. {$else}
  204. mov ExitCode,%ebx
  205. {$endif}
  206. {$endif FPC_PIC}
  207. int $0x80
  208. jmp .Lhaltproc
  209. end;
  210. end;