crt1.S 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /*
  2. * Copyright (C) 2004-2007 Atmel Corporation
  3. *
  4. * This file is subject to the terms and conditions of the GNU Lesser General
  5. * Public License. See the file "COPYING.LIB" in the main directory of this
  6. * archive for more details.
  7. *
  8. * When we enter _start, the stack looks like this:
  9. * argc argument counter
  10. * argv[0] pointer to program name
  11. * argv[1..argc-1] pointers to program args
  12. * NULL
  13. * env[0..N] pointers to environment variables
  14. * NULL
  15. *
  16. * r12 contains a function pointer to be registered with `atexit'.
  17. * This is how the dynamic linker arranges to have DT_FINI functions
  18. * called for shared libraries that have been loaded before this
  19. * code runs.
  20. *
  21. * We're going to call the following function:
  22. * __uClibc_main(int (*main)(int, char **, char **), int argc,
  23. * char **argv, void (*app_init)(void), void (*app_fini)(void),
  24. * void (*rtld_fini)(void), void *stack_end)
  25. *
  26. * So we need to set up things as follows:
  27. * r12 = address of main
  28. * r11 = argc
  29. * r10 = &argv[0]
  30. * r9 = address of _init
  31. * r8 = address of _fini
  32. * sp[0] = whatever we got passed in r12
  33. */
  34. #include <features.h>
  35. .text
  36. .global _start
  37. .type _start, @function
  38. _start:
  39. /* Clear the frame pointer and link register since this is the outermost frame. */
  40. mov r7, 0
  41. mov lr, 0
  42. ld.w r11, sp++ /* argc */
  43. mov r10, sp /* &argv[0] */
  44. st.w --sp, r10 /* stack_end */
  45. st.w --sp, r12 /* rtld_fini */
  46. #ifdef __PIC__
  47. lddpc r6, .L_GOT
  48. .L_RGOT:
  49. rsub r6, pc
  50. lda.w r9, _init
  51. lda.w r8, _fini
  52. lda.w r12, main
  53. /* Ok, now run uClibc's main() -- should not return */
  54. call __uClibc_main
  55. .align 2
  56. .L_GOT:
  57. .long .L_RGOT - _GLOBAL_OFFSET_TABLE_
  58. #else
  59. lddpc r9, __init_addr /* app_init */
  60. lddpc r8, __fini_addr /* app_fini */
  61. lddpc r12, __main_addr /* main */
  62. /* Ok, now run uClibc's main() -- should not return */
  63. lddpc pc, ___uClibc_main_addr
  64. .align 2
  65. __init_addr:
  66. .long _init
  67. __fini_addr:
  68. .long _fini
  69. __main_addr:
  70. .long main
  71. ___uClibc_main_addr:
  72. .long __uClibc_main
  73. #endif
  74. .size _start, . - _start
  75. /*
  76. * The LSB says we need this.
  77. */
  78. .section ".note.ABI-tag", "a"
  79. .align 4
  80. .long 2f - 1f /* namesz */
  81. .long 4f - 3f /* descsz */
  82. .long 1 /* type */
  83. 1: .asciz "GNU" /* name */
  84. 2: .align 4
  85. 3: .long 0 /* Linux executable */
  86. .long 2,6,0 /* Earliest compatible kernel */
  87. 4: .align 4