dl-startup.h 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #define LDSO_NEED_DPNT
  2. unsigned int _dl_nios2_get_gp_value(ElfW(Dyn) *dpnt);
  3. unsigned int
  4. _dl_nios2_get_gp_value (ElfW(Dyn) *dpnt)
  5. {
  6. while (dpnt->d_tag != DT_NULL) {
  7. if (dpnt->d_tag == DT_NIOS2_GP) {
  8. return (unsigned int)(dpnt->d_un.d_ptr);
  9. }
  10. ++dpnt;
  11. }
  12. return 0;
  13. }
  14. __asm__ (
  15. ".text\n"
  16. ".globl _start\n"
  17. ".type _start, %function\n"
  18. "_start:\n"
  19. " /* At start time, all the args are on the stack. */\n"
  20. " mov r4, sp\n"
  21. "\n"
  22. " /* Start the calculation of the GOT pointer. */\n"
  23. " nextpc r22\n"
  24. "1: movhi r8, %hiadj(_gp_got - 1b)\n"
  25. " addi r8, r8, %lo(_gp_got - 1b)\n"
  26. "\n"
  27. " /* Figure out where _dl_start will need to return to. */\n"
  28. " movhi ra, %hiadj(2f - 1b)\n"
  29. " addi ra, ra, %lo(2f - 1b)\n"
  30. " add ra, ra, r22\n"
  31. "\n"
  32. " /* Finish the calculation of the GOT pointer. */\n"
  33. " add r22, r22, r8\n"
  34. "\n"
  35. " br _dl_start\n"
  36. "\n"
  37. " /* Save the returned user entry point. */\n"
  38. "2: mov r16, r2\n"
  39. "\n"
  40. " /* Initialize gp. */\n"
  41. " ldw r4, %got(_dl_saved_dpnt)(r22)\n"
  42. " ldw r8, %call(_dl_nios2_get_gp_value)(r22)\n"
  43. " callr r8\n"
  44. " mov gp, r2\n"
  45. "\n"
  46. " /* Find the number of arguments to skip. */\n"
  47. " ldw r8, %got(_dl_skip_args)(r22)\n"
  48. " ldw r8, 0(r8)\n"
  49. "\n"
  50. " /* Find argc. */\n"
  51. " ldw r5, 0(sp)\n"
  52. " sub r5, r5, r8\n"
  53. " stw r5, 0(sp)\n"
  54. "\n"
  55. " /* Find the first unskipped argument. */\n"
  56. " slli r8, r8, 2\n"
  57. " addi r6, sp, 4\n"
  58. " add r9, r6, r8\n"
  59. " mov r10, r6\n"
  60. "\n"
  61. " /* Shuffle envp down. */\n"
  62. " mov r7, r10\n"
  63. "3: ldw r11, 0(r9)\n"
  64. " stw r11, 0(r10)\n"
  65. " addi r9, r9, 4\n"
  66. " addi r10, r10, 4\n"
  67. " bne r11, zero, 3b\n"
  68. "\n"
  69. " /* Shuffle auxv down. */\n"
  70. "4: ldw r11, 4(r9)\n"
  71. " stw r11, 4(r10)\n"
  72. " ldw r11, 0(r9)\n"
  73. " stw r11, 0(r10)\n"
  74. " addi r9, r9, 8\n"
  75. " addi r10, r10, 8\n"
  76. " bne r11, zero, 4b\n"
  77. "\n"
  78. " /* Jump to the user's entry point. */\n"
  79. " jmp r16\n"
  80. );
  81. /*
  82. * Get a pointer to the argv array. On many platforms this can be just
  83. * the address of the first argument, on other platforms we need to
  84. * do something a little more subtle here.
  85. */
  86. #define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long*) ARGS)+1)
  87. /* We can't call functions earlier in the dl startup process */
  88. #define NO_FUNCS_BEFORE_BOOTSTRAP
  89. /* The ld.so library requires relocations */
  90. #define ARCH_NEEDS_BOOTSTRAP_RELOCS
  91. static __always_inline
  92. void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr,
  93. unsigned long symbol_addr, unsigned long load_addr, attribute_unused Elf32_Sym *symtab)
  94. {
  95. switch (ELF_R_TYPE(rpnt->r_info)) {
  96. case R_NIOS2_RELATIVE:
  97. *reloc_addr = load_addr + rpnt->r_addend;
  98. break;
  99. default:
  100. _dl_exit(1);
  101. break;
  102. }
  103. }