start.S 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /* Startup code compliant to the ELF x86-64 ABI.
  2. Copyright (C) 2001-2026 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. In addition to the permissions in the GNU Lesser General Public
  9. License, the Free Software Foundation gives you unlimited
  10. permission to link the compiled version of this file with other
  11. programs, and to distribute those programs without any restriction
  12. coming from the use of this file. (The GNU Lesser General Public
  13. License restrictions do apply in other respects; for example, they
  14. cover modification of the file, and distribution when not linked
  15. into another program.)
  16. Note that people who make modified versions of this file are not
  17. obligated to grant this special exception for their modified
  18. versions; it is their choice whether to do so. The GNU Lesser
  19. General Public License gives permission to release a modified
  20. version without this exception; this exception also makes it
  21. possible to release a modified version which carries forward this
  22. exception.
  23. The GNU C Library is distributed in the hope that it will be useful,
  24. but WITHOUT ANY WARRANTY; without even the implied warranty of
  25. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  26. Lesser General Public License for more details.
  27. You should have received a copy of the GNU Lesser General Public
  28. License along with the GNU C Library; if not, see
  29. <https://www.gnu.org/licenses/>. */
  30. /* This is the canonical entry point, usually the first thing in the text
  31. segment. The SVR4/i386 ABI (pages 3-31, 3-32) says that when the entry
  32. point runs, most registers' values are unspecified, except for:
  33. %rdx Contains a function pointer to be registered with `atexit'.
  34. This is how the dynamic linker arranges to have DT_FINI
  35. functions called for shared libraries that have been loaded
  36. before this code runs.
  37. %rsp The stack contains the arguments and environment:
  38. 0(%rsp) argc
  39. LP_SIZE(%rsp) argv[0]
  40. ...
  41. (LP_SIZE*argc)(%rsp) NULL
  42. (LP_SIZE*(argc+1))(%rsp) envp[0]
  43. ...
  44. NULL
  45. */
  46. #include <sysdep.h>
  47. ENTRY (_start)
  48. /* Clearing frame pointer is insufficient, use CFI. */
  49. cfi_undefined (rip)
  50. /* Clear the frame pointer. The ABI suggests this be done, to mark
  51. the outermost frame obviously. */
  52. xorl %ebp, %ebp
  53. /* Extract the arguments as encoded on the stack and set up
  54. the arguments for __libc_start_main (int (*main) (int, char **, char **),
  55. int argc, char *argv,
  56. void (*init) (void), void (*fini) (void),
  57. void (*rtld_fini) (void), void *stack_end).
  58. The arguments are passed via registers and on the stack:
  59. main: %rdi
  60. argc: %rsi
  61. argv: %rdx
  62. init: %rcx
  63. fini: %r8
  64. rtld_fini: %r9
  65. stack_end: stack. */
  66. mov %RDX_LP, %R9_LP /* Address of the shared library termination
  67. function. */
  68. #ifdef __ILP32__
  69. mov (%rsp), %esi /* Simulate popping 4-byte argument count. */
  70. add $4, %esp
  71. #else
  72. popq %rsi /* Pop the argument count. */
  73. #endif
  74. /* argv starts just at the current stack top. */
  75. mov %RSP_LP, %RDX_LP
  76. /* Align the stack to a 16 byte boundary to follow the ABI. */
  77. and $~15, %RSP_LP
  78. /* Push garbage because we push 8 more bytes. */
  79. pushq %rax
  80. /* Provide the highest stack address to the user code (for stacks
  81. which grow downwards). */
  82. pushq %rsp
  83. /* These used to be the addresses of .fini and .init. */
  84. xorl %r8d, %r8d
  85. xorl %ecx, %ecx
  86. #ifdef PIC
  87. mov main@GOTPCREL(%rip), %RDI_LP
  88. #else
  89. mov $main, %RDI_LP
  90. #endif
  91. /* Call the user's main function, and exit with its value.
  92. But let the libc call main. Since __libc_start_main in
  93. libc.so is called very early, lazy binding isn't relevant
  94. here. Use indirect branch via GOT to avoid extra branch
  95. to PLT slot. In case of static executable, ld in binutils
  96. 2.26 or above can convert indirect branch into direct
  97. branch. */
  98. call *__libc_start_main@GOTPCREL(%rip)
  99. hlt /* Crash if somehow `exit' does return. */
  100. END (_start)
  101. /* Define a symbol for the first piece of initialized data. */
  102. .data
  103. .globl __data_start
  104. __data_start:
  105. .long 0
  106. .weak data_start
  107. data_start = __data_start