start.inc 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2009 by Pierre Muller,
  4. member of the Free Pascal development team.
  5. Program startup
  6. Adapted from source code on opensolaris 2.11
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  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. * CDDL HEADER START
  16. *
  17. * The contents of this file are subject to the terms of the
  18. * Common Development and Distribution License (the "License").
  19. * You may not use this file except in compliance with the License.
  20. *
  21. * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  22. * or http://www.opensolaris.org/os/licensing.
  23. * See the License for the specific language governing permissions
  24. * and limitations under the License.
  25. *
  26. * When distributing Covered Code, include this CDDL HEADER in each
  27. * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  28. * If applicable, add the following below this CDDL HEADER, with the
  29. * fields enclosed by brackets "[]" replaced with your own identifying
  30. * information: Portions Copyright [yyyy] [name of copyright owner]
  31. *
  32. * CDDL HEADER END
  33. */
  34. /*
  35. * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
  36. * Use is subject to license terms.
  37. */
  38. *)
  39. (*
  40. /*
  41. * This crt1.o module is provided as the bare minimum required to build
  42. * a 64-bit executable with gcc. It is installed in /usr/lib/amd64
  43. * where it will be picked up by gcc, along with crti.o and crtn.o
  44. */
  45. .ident "%Z%%M% %I% %E% SMI"
  46. .file "crt1.s"
  47. .globl _start
  48. /* global entities defined elsewhere but used here */
  49. .globl main
  50. .globl __fpstart
  51. .globl exit
  52. .globl _exit
  53. .weak _DYNAMIC
  54. *)
  55. type
  56. TCdeclProcedure = procedure; cdecl;
  57. function atexit(proc:TCdeclProcedure):longint;cdecl;external 'c' name 'atexit'{ @plt };
  58. procedure C_exit;cdecl;external 'c' name 'exit';
  59. procedure _exit;cdecl;external 'c' name '_exit';
  60. //procedure _fini;cdecl;external 'c' name '_fini';
  61. //procedure __fpstart;cdecl;external 'c' name '__fpstart'{ @plt };
  62. //procedure __fsr;cdecl;external 'c' name '__fsr';
  63. //procedure _init;cdecl;external 'c' name '_init';
  64. procedure PascalMain;external name 'PASCALMAIN';
  65. {vars are not correctly transformed :(
  66. var
  67. _DYNAMIC : longint; cvar; external;
  68. __Argv : pointer; cvar; external;
  69. environ : pointer; cvar; external;
  70. __get_exit_frame_monitor_ptr : pointer; cvar; external;
  71. __do_exit_code_ptr : pointer; cvar; external;
  72. }
  73. (*
  74. .section .data
  75. .weak environ
  76. .set environ,_environ
  77. .globl _environ
  78. .type _environ,@object
  79. .size _environ,8
  80. .align 8
  81. _environ:
  82. .8byte 0x0
  83. .globl __environ_lock
  84. .type __environ_lock,@object
  85. .size __environ_lock,24
  86. .align 8
  87. __environ_lock:
  88. .zero 24
  89. .globl ___Argv
  90. .type ___Argv,@object
  91. .size ___Argv,8
  92. .align 8
  93. ___Argv:
  94. .8byte 0x0
  95. .globl __longdouble_used
  96. .section .data
  97. .align 8
  98. .type __longdouble_used,@object
  99. .size __longdouble_used,4
  100. __longdouble_used:
  101. .4byte 0
  102. *)
  103. var
  104. _environ : pointer; cvar; public;
  105. __environ_lock : Array[0..24-1] of byte; cvar; public;
  106. ___Argv : pointer;cvar; public;
  107. __longdouble_used : longint; cvar; public;
  108. var
  109. _DYNAMIC : pointer;cvar;weakexternal;
  110. //procedure _DYNAMIC;cdecl;external 'c' name '_DYNAMIC'; { should be weak }
  111. (*
  112. /*
  113. * The SVR4/i386 ABI (pages 3-29) says that when the entry
  114. * point runs registers' %rbp, %rsp, %rdx values are specified
  115. * the following:
  116. *
  117. * %rbp The content of this register is unspecified at
  118. * process initialization time, but the user code should mark
  119. * the deepest stack frame by setting the frame pointer to zero.
  120. * No other frame's %ebp should have a zero value.
  121. *
  122. * %rsp Performing its usual job, the stack pointer holds the address
  123. * of the bottom of the stack, which is guaranteed to be
  124. * quadword aligned.
  125. *
  126. * The stack contains the arguments and environment:
  127. * ...
  128. * envp[0] (16+(8*argc))(%rsp)
  129. * NULL (8+(8*argc))(%rsp)
  130. * ...
  131. * argv[0] 8(%rsp)
  132. * argc 0(%rsp)
  133. *
  134. * %rdx In a conforming program, this register contains a function
  135. * pointer that the application should register with atexit(BA_OS).
  136. * This function is used for shared object termination code
  137. * [see Dynamic Linking in Chapter 5 of the System V ABI].
  138. *
  139. */
  140. *)
  141. procedure _start;assembler;nostackframe;public name '_start';
  142. asm
  143. (*
  144. /*
  145. * Allocate a NULL return address and a NULL previous %rbp as if
  146. * there was a genuine call to _start.
  147. */
  148. *)
  149. movq %rsp,%rax
  150. // Save %rsp to StackTopPtr
  151. {$ifdef FPC_PIC}
  152. movq StackTopPtr@GOTPCREL(%rip),%rcx
  153. {$else FPC_PIC}
  154. movq $StackTopPtr,%rcx
  155. {$endif FPC_PIC}
  156. movq %rax,(%rcx)
  157. pushq $0x0
  158. pushq $0x0
  159. movq %rsp,%rbp
  160. (*
  161. /*
  162. * The stack now is
  163. *
  164. * envp[0] (32+(8*argc))(%rsp) - (A)
  165. * NULL (24+(8*argc))(%rsp)
  166. * ...
  167. * argv[0] 24(%rbp) - (B)
  168. * argc 16(%rbp)
  169. * 0 8(%rbp)
  170. * 0 0(%rbp)
  171. */
  172. *)
  173. {$ifdef FPC_PIC}
  174. movq _DYNAMIC@GOTPCREL(%rip),%rax
  175. {$else FPC_PIC}
  176. movq $_DYNAMIC,%rax
  177. {$endif FPC_PIC}
  178. testq %rax,%rax
  179. je .Label1
  180. movq %rdx,%rdi { register rt_do_exit }
  181. call atexit{$ifdef FPC_PIC}@PLT{$endif}
  182. .Label1:
  183. (* What should we do about this?
  184. movq $_fini,%rdi
  185. call atexit *)
  186. (*
  187. /*
  188. * Calculate the location of the envp array by adding the size of
  189. * the argv array to the start of the argv array.
  190. */
  191. *)
  192. movq 0x10(%rbp),%rax
  193. {$ifdef FPC_PIC}
  194. movq argc@GOTPCREL(%rip),%rcx
  195. {$else FPC_PIC}
  196. movq $argc,%rcx
  197. {$endif FPC_PIC}
  198. movl %eax,(%rcx)
  199. {$ifdef FPC_PIC}
  200. movq _environ@GOTPCREL(%rip),%rcx
  201. movq (%rcx),%rcx
  202. {$else FPC_PIC}
  203. movq _environ(%rip),%rcx
  204. {$endif FPC_PIC}
  205. testq %rcx,%rcx
  206. jne .Label3
  207. lea 0x20(%rbp,%rax,8),%rcx
  208. .Label3:
  209. {$ifdef FPC_PIC}
  210. movq _environ@GOTPCREL(%rip),%rbx
  211. movq %rcx,(%rbx)
  212. {$else FPC_PIC}
  213. movq %rcx,_environ(%rip)
  214. {$endif FPC_PIC}
  215. // Specific to Free Pascal
  216. {$ifdef FPC_PIC}
  217. movq envp@GOTPCREL(%rip),%rbx
  218. movq %rcx,(%rbx)
  219. {$else FPC_PIC}
  220. movq %rcx,envp(%rip)
  221. {$endif FPC_PIC}
  222. (*
  223. /*
  224. * Force stack alignment - below here there must have been an even
  225. * number of un-popped pushq instructions whenever a call is reached
  226. */
  227. *)
  228. andq $-16,%rsp
  229. pushq %rdx
  230. leaq 24(%rbp),%rdx { argv (B) }
  231. {$ifdef FPC_PIC}
  232. movq ___Argv@GOTPCREL(%rip),%rbx
  233. movq %rdx,(%rbx)
  234. {$else FPC_PIC}
  235. movq %rdx,___Argv(%rip)
  236. {$endif FPC_PIC}
  237. {$ifdef FPC_PIC}
  238. movq argv@GOTPCREL(%rip),%rbx
  239. {$else FPC_PIC}
  240. movq $argv,%rbx
  241. {$endif FPC_PIC}
  242. movq %rdx,(%rbx)
  243. pushq %rcx
  244. pushq %rdx
  245. pushq %rax
  246. (* Should this be done, and where?
  247. call __fpstart
  248. call _init *)
  249. popq %rdi
  250. popq %rsi
  251. popq %rdx
  252. popq %rcx
  253. call PASCALMAIN{$ifdef FPC_PIC}@PLT{$endif} { main(argc,argv,envp) }
  254. pushq %rax
  255. pushq %rax
  256. movq %rax,%rdi { and call exit }
  257. call C_exit{$ifdef FPC_PIC}@PLT{$endif}
  258. popq %rdi
  259. popq %rdi
  260. call _exit{$ifdef FPC_PIC}@PLT{$endif} { if user redefined exit, call _exit }
  261. hlt
  262. end;
  263. (*
  264. /*
  265. * The following is here in case any object module compiled with cc -p
  266. * was linked into this module.
  267. */
  268. .globl _mcount
  269. .section .text
  270. .align 8
  271. .type _mcount,@function
  272. _mcount:
  273. ret
  274. .size _mcount, .-_mcount
  275. *)