gprt0.as 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /* This is the canonical entry point, usually the first thing in the text
  2. segment. The SVR4/i386 ABI (pages 3-31, 3-32) says that when the entry
  3. point runs, most registers' values are unspecified, except for:
  4. %rdx Contains a function pointer to be registered with `atexit'.
  5. This is how the dynamic linker arranges to have DT_FINI
  6. functions called for shared libraries that have been loaded
  7. before this code runs.
  8. %rsp The stack contains the arguments and environment:
  9. 0(%rsp) argc
  10. 8(%rsp) argv[0]
  11. ...
  12. (8*argc)(%rsp) NULL
  13. (8*(argc+1))(%rsp) envp[0]
  14. ...
  15. NULL
  16. */
  17. .text
  18. .globl _start
  19. .type _start,@function
  20. _start:
  21. /* Clear the frame pointer. The ABI suggests this be done, to mark
  22. the outermost frame obviously. */
  23. xorq %rbp, %rbp
  24. /* Extract the arguments as encoded on the stack and set up
  25. the arguments for __libc_start_main (int (*main) (int, char **, char **),
  26. int argc, char *argv,
  27. void (*init) (void), void (*fini) (void),
  28. void (*rtld_fini) (void), void *stack_end).
  29. The arguments are passed via registers and on the stack:
  30. main: %rdi
  31. argc: %rsi
  32. argv: %rdx
  33. init: %rcx
  34. fini: %r8
  35. rtld_fini: %r9
  36. stack_end: stack. */
  37. movq %rdx, %r9 /* Address of the shared library termination
  38. function. */
  39. popq %rsi /* Pop the argument count. */
  40. movq %rsp, %rdx /* argv starts just at the current stack top. */
  41. movq %rsi,operatingsystem_parameter_argc
  42. movq %rsp,operatingsystem_parameter_argv /* argv starts just at the current stack top. */
  43. leaq 8(,%rsi,8),%rax
  44. addq %rsp,%rax
  45. movq %rax,operatingsystem_parameter_envp
  46. /* Align the stack to a 16 byte boundary to follow the ABI. */
  47. andq $~15, %rsp
  48. pushq %rax /* Push garbage because we push 8 more bytes. */
  49. /* Provide the highest stack address to the user code (for stacks
  50. which grow downwards). */
  51. pushq %rsp
  52. /* Pass address of our own entry points to .fini and .init. */
  53. movq $_init_dummy, %r8
  54. movq $_fini_dummy, %rcx
  55. movq $main_stub, %rdi
  56. /* Call the user's main function, and exit with its value.
  57. But let the libc call main. */
  58. call __libc_start_main
  59. hlt /* Crash if somehow `exit' does return. */
  60. /* fake main routine which will be run from libc */
  61. main_stub:
  62. /* save return address */
  63. popq %rax
  64. // stack alignment
  65. pushq %rax
  66. movq %rax,___fpc_ret
  67. movq %rbp,___fpc_ret_rbp
  68. pushq %rax
  69. /* Initialize gmon */
  70. movq $_etext,%rsi
  71. movq $_start,%rdi
  72. call monstartup
  73. movq $_mcleanup,%rdi
  74. call atexit
  75. /* Save initial stackpointer */
  76. movq %rsp,__stkptr
  77. /* start the program */
  78. xorq %rbp,%rbp
  79. call PASCALMAIN
  80. hlt
  81. .globl _haltproc
  82. .type _haltproc,@function
  83. _haltproc:
  84. movzwq operatingsystem_result,%rax /* load and save exitcode */
  85. movq ___fpc_ret,%rdx /* return to libc */
  86. movq ___fpc_ret_rbp,%rbp
  87. pushq %rdx
  88. _init_dummy:
  89. _fini_dummy:
  90. ret
  91. /* Define a symbol for the first piece of initialized data. */
  92. .data
  93. .globl __data_start
  94. __data_start:
  95. .long 0
  96. .weak data_start
  97. data_start = __data_start
  98. .globl ___fpc_brk_addr /* heap management */
  99. .type ___fpc_brk_addr,@object
  100. .size ___fpc_brk_addr,8
  101. ___fpc_brk_addr:
  102. .quad 0
  103. ___fpc_ret: /* return address to libc */
  104. .quad 0
  105. ___fpc_ret_rbp:
  106. .quad 0
  107. .bss
  108. .comm __stkptr,8
  109. .comm operatingsystem_parameter_envp,8
  110. .comm operatingsystem_parameter_argc,8
  111. .comm operatingsystem_parameter_argv,8
  112. /* We need this stuff to make gdb behave itself, otherwise
  113. gdb will chokes with SIGILL when trying to debug apps.
  114. */
  115. .section ".note.ABI-tag", "a"
  116. .align 4
  117. .long 1f - 0f
  118. .long 3f - 2f
  119. .long 1
  120. 0: .asciz "GNU"
  121. 1: .align 4
  122. 2: .long 0
  123. .long 2,4,0
  124. 3: .align 4
  125. .section .note.GNU-stack,"",@progbits