crt1.S 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /* When we enter this piece of code, the program stack looks like this:
  2. argc argument counter (integer)
  3. argv[0] program name (pointer)
  4. argv[1...N] program args (pointers)
  5. argv[argc-1] end of args (integer)
  6. NULL
  7. env[0...N] environment variables (pointers)
  8. NULL
  9. For uClinux it looks like this:
  10. argc argument counter (integer)
  11. argv char *argv[]
  12. envp char *envp[]
  13. argv[0] program name (pointer)
  14. argv[1...N] program args (pointers)
  15. argv[argc-1] end of args (integer)
  16. NULL
  17. env[0...N] environment variables (pointers)
  18. NULL
  19. When we are done here, we want
  20. a1=argc
  21. a2=argv[0]
  22. a3=argv[argc+1]
  23. ARM register quick reference:
  24. Name Number ARM Procedure Calling Standard Role
  25. a1 r0 argument 1 / integer result / scratch register / argc
  26. a2 r1 argument 2 / scratch register / argv
  27. a3 r2 argument 3 / scratch register / envp
  28. a4 r3 argument 4 / scratch register
  29. v1 r4 register variable
  30. v2 r5 register variable
  31. v3 r6 register variable
  32. v4 r7 register variable
  33. v5 r8 register variable
  34. sb/v6 r9 static base / register variable
  35. sl/v7 r10 stack limit / stack chunk handle / reg. variable
  36. fp r11 frame pointer
  37. ip r12 scratch register / new-sb in inter-link-unit calls
  38. sp r13 lower end of current stack frame
  39. lr r14 link address / scratch register
  40. pc r15 program counter
  41. */
  42. #include <features.h>
  43. .text
  44. .global _start
  45. .type _start,%function
  46. .type _init,%function
  47. .type _fini,%function
  48. .type main,%function
  49. .type __uClibc_main,%function
  50. .text
  51. _start:
  52. /* clear the frame pointer */
  53. mov fp, #0
  54. #ifdef __PIC__
  55. /* Store the address of main in r0 */
  56. adr r5, .L_main
  57. ldr r0, .L_main
  58. add r0, r0, r5
  59. #else
  60. /* Store the address of main in r0 */
  61. ldr r0, =main
  62. #endif
  63. #ifdef __ARCH_HAS_MMU__
  64. /* Load register r1 (argc) from the stack to its final resting place */
  65. ldr r1, [sp], #4
  66. /* Copy argv pointer into r2 -- which its final resting place */
  67. mov r2, sp
  68. #else
  69. /*
  70. * uClinux stacks look a little different from normal
  71. * MMU-full Linux stacks (for no good reason)
  72. */
  73. /* pull argc, argv and envp off the stack */
  74. ldr r1,[sp, #0]
  75. ldr r2,[sp, #4]
  76. #endif
  77. #ifdef __PIC__
  78. /* Store the address of _init in r3 */
  79. adr r5, .L_init
  80. ldr r3, .L_init
  81. add r3, r3, r5
  82. /* Push _fini onto the stack as an argument to main() */
  83. ldr r4, .L_init + 4
  84. add r4, r4, r5
  85. stmfd sp!, {r4}
  86. /* Push rtld_fini onto the stack as an argument to main() */
  87. ldr r4, .L_init + 8
  88. add r4, r4, r5
  89. stmfd sp!, {r4}
  90. #else
  91. /* Store the address of _init in r3 as an argument to main() */
  92. ldr r3, =_init
  93. /* Push _fini onto the stack as an argument to main() */
  94. ldr r4, =_fini
  95. stmfd sp!, {r4}
  96. /* Push rtld_fini onto the stack as an argument to main() */
  97. ldr r4, =rtld_fini
  98. stmfd sp!, {r4}
  99. #endif
  100. /* We need to call __uClibc_main which should not return.
  101. __uClibc_main (int (*main) (int, char **, char **), int argc,
  102. char **argv, void (*init) (void), void (*fini) (void),
  103. void (*rtld_fini) (void), void *stack_end)
  104. */
  105. bl __uClibc_main
  106. /* Crash if somehow `exit' returns anyways. */
  107. bl abort
  108. #ifdef __PIC__
  109. .L_init:
  110. .word _init
  111. .word _fini
  112. .word rtld_fini
  113. .L_main:
  114. .word main
  115. #endif
  116. /* We need this stuff to make gdb behave itself, otherwise
  117. gdb will choke with SIGILL when trying to debug apps.
  118. */
  119. .section ".note.ABI-tag", "a"
  120. .align 4
  121. .long 1f - 0f
  122. .long 3f - 2f
  123. .long 1
  124. 0: .asciz "GNU"
  125. 1: .align 4
  126. 2: .long 0
  127. .long 2,0,0
  128. 3: .align 4
  129. /* Define a symbol for the first piece of initialized data. */
  130. .data
  131. .globl __data_start
  132. __data_start:
  133. .long 0
  134. .weak data_start
  135. data_start = __data_start