dl-startup.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /* Any assmbly language/system dependent hacks needed to setup boot1.c so it
  2. * will work as expected and cope with whatever platform specific wierdness is
  3. * needed for this architecture.
  4. */
  5. asm("" \
  6. " .text\n" \
  7. " .globl _dl_boot\n" \
  8. "_dl_boot:\n" \
  9. " .set noreorder\n" \
  10. " bltzal $0, 0f\n" \
  11. " nop\n" \
  12. "0: .cpload $31\n" \
  13. " .set reorder\n" \
  14. " la $4, _DYNAMIC\n" \
  15. " sw $4, -0x7ff0($28)\n" \
  16. " move $4, $29\n" \
  17. " la $8, coff\n" \
  18. " .set noreorder\n" \
  19. " bltzal $0, coff\n" \
  20. " nop\n" \
  21. "coff: subu $8, $31, $8\n" \
  22. " .set reorder\n" \
  23. " la $25, _dl_boot2\n" \
  24. " addu $25, $8\n" \
  25. " jalr $25\n" \
  26. " lw $4, 0($29)\n" \
  27. " la $5, 4($29)\n" \
  28. " sll $6, $4, 2\n" \
  29. " addu $6, $6, $5\n" \
  30. " addu $6, $6, 4\n" \
  31. " la $7, _dl_elf_main\n" \
  32. " lw $25, 0($7)\n" \
  33. " jr $25\n" \
  34. );
  35. #define DL_BOOT(X) static void __attribute_used__ _dl_boot2 (X)
  36. /*
  37. * Get a pointer to the argv array. On many platforms this can be just
  38. * the address if the first argument, on other platforms we need to
  39. * do something a little more subtle here.
  40. */
  41. #define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long *) ARGS)
  42. /*
  43. * Here is a macro to perform the GOT relocation. This is only
  44. * used when bootstrapping the dynamic loader.
  45. */
  46. #define PERFORM_BOOTSTRAP_GOT(got) \
  47. do { \
  48. Elf32_Sym *sym; \
  49. unsigned long i; \
  50. \
  51. /* Add load address displacement to all local GOT entries */ \
  52. i = 2; \
  53. while (i < tpnt->mips_local_gotno) \
  54. got[i++] += load_addr; \
  55. \
  56. /* Handle global GOT entries */ \
  57. got += tpnt->mips_local_gotno; \
  58. sym = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + \
  59. load_addr) + tpnt->mips_gotsym; \
  60. i = tpnt->mips_symtabno - tpnt->mips_gotsym; \
  61. \
  62. while (i--) { \
  63. if (sym->st_shndx == SHN_UNDEF || \
  64. sym->st_shndx == SHN_COMMON) \
  65. *got = load_addr + sym->st_value; \
  66. else if (ELF32_ST_TYPE(sym->st_info) == STT_FUNC && \
  67. *got != sym->st_value) \
  68. *got += load_addr; \
  69. else if (ELF32_ST_TYPE(sym->st_info) == STT_SECTION) { \
  70. if (sym->st_other == 0) \
  71. *got += load_addr; \
  72. } \
  73. else \
  74. *got = load_addr + sym->st_value; \
  75. \
  76. got++; \
  77. sym++; \
  78. } \
  79. } while (0)
  80. /*
  81. * Here is a macro to perform a relocation. This is only used when
  82. * bootstrapping the dynamic loader.
  83. */
  84. #define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \
  85. switch(ELF32_R_TYPE((RELP)->r_info)) { \
  86. case R_MIPS_REL32: \
  87. if (symtab_index) { \
  88. if (symtab_index < tpnt->mips_gotsym) \
  89. *REL += SYMBOL; \
  90. } \
  91. else { \
  92. *REL += LOAD; \
  93. } \
  94. break; \
  95. case R_MIPS_NONE: \
  96. break; \
  97. default: \
  98. SEND_STDERR("Aiieeee!"); \
  99. _dl_exit(1); \
  100. }
  101. /*
  102. * Transfer control to the user's application, once the dynamic loader
  103. * is done. This routine has to exit the current function, then
  104. * call the _dl_elf_main function. For MIPS, we do it in assembly
  105. * because the stack doesn't get properly restored otherwise. Got look
  106. * at boot1_arch.h
  107. */
  108. #define START()