dl-startup.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /* Copyright (C) 2003 Red Hat, Inc.
  2. Contributed by Alexandre Oliva <aoliva@redhat.com>
  3. This file is part of uClibc.
  4. uClibc is free software; you can redistribute it and/or modify it
  5. under the terms of the GNU Lesser General Public License as
  6. published by the Free Software Foundation; either version 2.1 of the
  7. License, or (at your option) any later version.
  8. uClibc is distributed in the hope that it will be useful, but WITHOUT
  9. ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Library General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with uClibc; see the file COPYING.LIB. If not, write to
  14. the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
  15. USA. */
  16. /* Any assembly language/system dependent hacks needed to setup
  17. * boot1.c so it will work as expected and cope with whatever platform
  18. * specific wierdness is needed for this architecture.
  19. * We override the default _dl_boot function, and replace it with a
  20. * bit of asm. Then call the real _dl_boot function, which is now
  21. * named _dl_boot2. */
  22. /* At program start-up, gr16 contains a pointer to a
  23. elf32_fdpic_loadmap that describes how the executable was loaded
  24. into memory. gr17 contains a pointer to the interpreter (our!)
  25. loadmap, if there is an interpreter, or 0 if we're being run as an
  26. executable. gr18 holds a pointer to the interpreter's dynamic
  27. section, if there is an interpreter, or to the executable's dynamic
  28. section, otherwise. If the executable is not dynamic, gr18 is 0.
  29. We rely on the fact that the linker adds a pointer to the
  30. _GLOBAL_OFFSET_TABLE_ as the last ROFIXUP entry, and that
  31. __self_reloc returns the relocated pointer to us, so that we can
  32. use this value to initialize the PIC register. */
  33. asm("" \
  34. " .text\n" \
  35. " .global _dl_boot\n" \
  36. " .type _dl_boot,@function\n" \
  37. "_dl_boot:\n" \
  38. " call .Lcall\n" \
  39. ".Lcall:\n" \
  40. " movsg lr, gr4\n" \
  41. " sethi.p #gprelhi(.Lcall), gr5\n"\
  42. " setlo #gprello(.Lcall), gr5\n"\
  43. " mov.p gr17, gr8\n" \
  44. " cmp gr17, gr0, icc0\n" \
  45. " sub.p gr4, gr5, gr4\n" \
  46. " ckeq icc0, cc4\n" \
  47. " cmov.p gr16, gr8, cc4, 1\n" \
  48. " sethi #gprelhi(__ROFIXUP_LIST__), gr9\n" \
  49. " sethi.p #gprelhi(__ROFIXUP_END__), gr10\n" \
  50. " setlo #gprello(__ROFIXUP_LIST__), gr9\n" \
  51. " setlo.p #gprello(__ROFIXUP_END__), gr10\n" \
  52. " add gr9, gr4, gr9\n" \
  53. " add.p gr10, gr4, gr10\n" \
  54. " call __self_reloc\n" \
  55. " mov.p gr8, gr15\n" \
  56. " mov gr16, gr9\n" \
  57. " mov.p gr17, gr10\n" \
  58. " mov gr18, gr11\n" \
  59. " addi.p sp, #4, gr13\n" \
  60. " addi sp, #-8, sp\n" \
  61. " mov.p sp, gr12\n" \
  62. " call _dl_boot2\n" \
  63. " ldd.p @(sp, gr0), gr14\n" \
  64. " addi sp, #8, sp\n" \
  65. " movgs gr0, lr\n" \
  66. " jmpl @(gr14, gr0)\n" \
  67. " .size _dl_boot,.-_dl_boot\n" \
  68. );
  69. #define _dl_boot _dl_boot2
  70. #define DL_BOOT(X) \
  71. static void __attribute__ ((used)) \
  72. _dl_boot (void *dl_boot_got_pointer, \
  73. struct elf32_fdpic_loadmap *dl_boot_progmap, \
  74. struct elf32_fdpic_loadmap *dl_boot_ldsomap, \
  75. Elf32_Dyn *dl_boot_ldso_dyn_pointer, \
  76. struct funcdesc_value *dl_main_funcdesc, \
  77. X)
  78. struct elf32_fdpic_loadmap;
  79. /*
  80. * Get a pointer to the argv array. On many platforms this can be just
  81. * the address if the first argument, on other platforms we need to
  82. * do something a little more subtle here.
  83. */
  84. #define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long*) ARGS)
  85. /*
  86. * Compute the GOT address. On several platforms, we use assembly
  87. * here. on FR-V FDPIC, there's no way to compute the GOT address,
  88. * since the offset between text and data is not fixed, so we arrange
  89. * for the assembly _dl_boot to pass this value as an argument to
  90. * _dl_boot. */
  91. #define DL_BOOT_COMPUTE_GOT(got) ((got) = dl_boot_got_pointer)
  92. #define DL_BOOT_COMPUTE_DYN(dpnt, got, load_addr) \
  93. ((dpnt) = dl_boot_ldso_dyn_pointer)
  94. /*
  95. * Here is a macro to perform a relocation. This is only used when
  96. * bootstrapping the dynamic loader. RELP is the relocation that we
  97. * are performing, REL is the pointer to the address we are relocating.
  98. * SYMBOL is the symbol involved in the relocation, and LOAD is the
  99. * load address.
  100. */
  101. #define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \
  102. switch(ELF32_R_TYPE((RELP)->r_info)){ \
  103. case R_FRV_32: \
  104. *(REL) += (SYMBOL); \
  105. break; \
  106. case R_FRV_FUNCDESC_VALUE: \
  107. { \
  108. struct funcdesc_value fv = { \
  109. (void*)((SYMBOL) + *(REL)), \
  110. (LOAD).got_value \
  111. }; \
  112. *(struct funcdesc_value volatile *)(REL) = fv; \
  113. break; \
  114. } \
  115. default: \
  116. _dl_exit(1); \
  117. }
  118. /*
  119. * Transfer control to the user's application, once the dynamic loader
  120. * is done. We return the address of the function's entry point to
  121. * _dl_boot, see boot1_arch.h.
  122. */
  123. #define START() do { \
  124. struct elf_resolve *exec_mod = _dl_loaded_modules; \
  125. dl_main_funcdesc->entry_point = _dl_elf_main; \
  126. while (exec_mod->libtype != elf_executable) \
  127. exec_mod = exec_mod->next; \
  128. dl_main_funcdesc->got_value = exec_mod->loadaddr.got_value; \
  129. /* _dl_dprintf(2, "entry point is (%x,%x)\n", dl_main_funcdesc->entry_point, dl_main_funcdesc->got_value); */ \
  130. return; \
  131. } while (0)