start.inc 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  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;cdecl;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. pushq $0x0
  150. pushq $0x0
  151. movq %rsp,%rbp
  152. (*
  153. /*
  154. * The stack now is
  155. *
  156. * envp[0] (32+(8*argc))(%rsp) - (A)
  157. * NULL (24+(8*argc))(%rsp)
  158. * ...
  159. * argv[0] 24(%rbp) - (B)
  160. * argc 16(%rbp)
  161. * 0 8(%rbp)
  162. * 0 0(%rbp)
  163. */
  164. *)
  165. {$ifdef FPC_PIC}
  166. movq _DYNAMIC@GOTPCREL(%rip),%rax
  167. {$else FPC_PIC}
  168. movq $_DYNAMIC,%rax
  169. {$endif FPC_PIC}
  170. testq %rax,%rax
  171. je .Label1
  172. movq %rdx,%rdi { register rt_do_exit }
  173. call atexit{$ifdef FPC_PIC}@PLT{$endif}
  174. .Label1:
  175. (* What should we do about this?
  176. movq $_fini,%rdi
  177. call atexit *)
  178. (*
  179. /*
  180. * Calculate the location of the envp array by adding the size of
  181. * the argv array to the start of the argv array.
  182. */
  183. *)
  184. movq 0x10(%rbp),%rax
  185. {$ifdef FPC_PIC}
  186. movq argc@GOTPCREL(%rip),%rcx
  187. {$else FPC_PIC}
  188. movq $argc,%rcx
  189. {$endif FPC_PIC}
  190. movl %eax,(%rcx)
  191. {$ifdef FPC_PIC}
  192. movq _environ@GOTPCREL(%rip),%rcx
  193. movq (%rcx),%rcx
  194. {$else FPC_PIC}
  195. movq _environ(%rip),%rcx
  196. {$endif FPC_PIC}
  197. testq %rcx,%rcx
  198. jne .Label3
  199. lea 0x20(%rbp,%rax,8),%rcx
  200. .Label3:
  201. {$ifdef FPC_PIC}
  202. movq _environ@GOTPCREL(%rip),%rbx
  203. movq %rcx,(%rbx)
  204. {$else FPC_PIC}
  205. movq %rcx,_environ(%rip)
  206. {$endif FPC_PIC}
  207. // Specific to Free Pascal
  208. {$ifdef FPC_PIC}
  209. movq envp@GOTPCREL(%rip),%rbx
  210. movq %rcx,(%rbx)
  211. {$else FPC_PIC}
  212. movq %rcx,envp(%rip)
  213. {$endif FPC_PIC}
  214. (*
  215. /*
  216. * Force stack alignment - below here there must have been an even
  217. * number of un-popped pushq instructions whenever a call is reached
  218. */
  219. *)
  220. andq $-16,%rsp
  221. pushq %rdx
  222. leaq 24(%rbp),%rdx { argv (B) }
  223. {$ifdef FPC_PIC}
  224. movq ___Argv@GOTPCREL(%rip),%rbx
  225. movq %rdx,(%rbx)
  226. {$else FPC_PIC}
  227. movq %rdx,___Argv(%rip)
  228. {$endif FPC_PIC}
  229. {$ifdef FPC_PIC}
  230. movq argv@GOTPCREL(%rip),%rbx
  231. {$else FPC_PIC}
  232. movq $argv,%rbx
  233. {$endif FPC_PIC}
  234. movq %rdx,(%rbx)
  235. pushq %rcx
  236. pushq %rdx
  237. pushq %rax
  238. (* Should this be done, and where?
  239. call __fpstart
  240. call _init *)
  241. popq %rdi
  242. popq %rsi
  243. popq %rdx
  244. popq %rcx
  245. call PASCALMAIN{$ifdef FPC_PIC}@PLT{$endif} { main(argc,argv,envp) }
  246. pushq %rax
  247. pushq %rax
  248. movq %rax,%rdi { and call exit }
  249. call C_exit{$ifdef FPC_PIC}@PLT{$endif}
  250. popq %rdi
  251. popq %rdi
  252. call _exit{$ifdef FPC_PIC}@PLT{$endif} { if user redefined exit, call _exit }
  253. hlt
  254. end;
  255. (*
  256. /*
  257. * The following is here in case any object module compiled with cc -p
  258. * was linked into this module.
  259. */
  260. .globl _mcount
  261. .section .text
  262. .align 8
  263. .type _mcount,@function
  264. _mcount:
  265. ret
  266. .size _mcount, .-_mcount
  267. *)