dl-startup.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /* Copyright (C) 2003 Red Hat, Inc.
  2. * Contributed by Alexandre Oliva <aoliva@redhat.com>
  3. *
  4. * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  5. */
  6. /* Any assembly language/system dependent hacks needed to setup
  7. * boot1.c so it will work as expected and cope with whatever platform
  8. * specific wierdness is needed for this architecture.
  9. * We override the default _dl_boot function, and replace it with a
  10. * bit of asm. Then call the real _dl_boot function, which is now
  11. * named _dl_boot2. */
  12. /* At program start-up, gr16 contains a pointer to a
  13. elf32_fdpic_loadmap that describes how the executable was loaded
  14. into memory. gr17 contains a pointer to the interpreter (our!)
  15. loadmap, if there is an interpreter, or 0 if we're being run as an
  16. executable. gr18 holds a pointer to the interpreter's dynamic
  17. section, if there is an interpreter, or to the executable's dynamic
  18. section, otherwise. If the executable is not dynamic, gr18 is 0.
  19. We rely on the fact that the linker adds a pointer to the
  20. _GLOBAL_OFFSET_TABLE_ as the last ROFIXUP entry, and that
  21. __self_reloc returns the relocated pointer to us, so that we can
  22. use this value to initialize the PIC register. */
  23. __asm__("" \
  24. " .text\n" \
  25. " .global _start\n" \
  26. " .type _start,@function\n" \
  27. " .hidden _start\n" \
  28. "_start:\n" \
  29. " call .Lcall\n" \
  30. ".Lcall:\n" \
  31. " movsg lr, gr4\n" \
  32. " sethi.p #gprelhi(.Lcall), gr5\n"\
  33. " setlo #gprello(.Lcall), gr5\n"\
  34. " mov.p gr17, gr8\n" \
  35. " cmp gr17, gr0, icc0\n" \
  36. " sub.p gr4, gr5, gr4\n" \
  37. " ckeq icc0, cc4\n" \
  38. " cmov.p gr16, gr8, cc4, 1\n" \
  39. " sethi #gprelhi(__ROFIXUP_LIST__), gr9\n" \
  40. " sethi.p #gprelhi(__ROFIXUP_END__), gr10\n" \
  41. " setlo #gprello(__ROFIXUP_LIST__), gr9\n" \
  42. " setlo.p #gprello(__ROFIXUP_END__), gr10\n" \
  43. " add gr9, gr4, gr9\n" \
  44. " add.p gr10, gr4, gr10\n" \
  45. " call __self_reloc\n" \
  46. " mov.p gr8, gr15\n" \
  47. " mov gr16, gr9\n" \
  48. " mov.p gr17, gr10\n" \
  49. " mov gr18, gr11\n" \
  50. " addi.p sp, #4, gr13\n" \
  51. " addi sp, #-8, sp\n" \
  52. " mov.p sp, gr12\n" \
  53. " call _dl_start\n" \
  54. " ldd.p @(sp, gr0), gr14\n" \
  55. " addi sp, #8, sp\n" \
  56. " movgs gr0, lr\n" \
  57. " jmpl @(gr14, gr0)\n" \
  58. " .size _start,.-_start\n" \
  59. );
  60. #undef DL_START
  61. #define DL_START(X) \
  62. static void __attribute__ ((used)) \
  63. _dl_start (Elf32_Addr dl_boot_got_pointer, \
  64. struct elf32_fdpic_loadmap *dl_boot_progmap, \
  65. struct elf32_fdpic_loadmap *dl_boot_ldsomap, \
  66. Elf32_Dyn *dl_boot_ldso_dyn_pointer, \
  67. struct funcdesc_value *dl_main_funcdesc, \
  68. X)
  69. /*
  70. * Get a pointer to the argv array. On many platforms this can be just
  71. * the address of the first argument, on other platforms we need to
  72. * do something a little more subtle here.
  73. */
  74. #define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long*) ARGS)
  75. /*
  76. * Here is a macro to perform a relocation. This is only used when
  77. * bootstrapping the dynamic loader. RELP is the relocation that we
  78. * are performing, REL is the pointer to the address we are relocating.
  79. * SYMBOL is the symbol involved in the relocation, and LOAD is the
  80. * load address.
  81. */
  82. #define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \
  83. switch(ELF_R_TYPE((RELP)->r_info)){ \
  84. case R_FRV_32: \
  85. *(REL) += (SYMBOL); \
  86. break; \
  87. case R_FRV_FUNCDESC_VALUE: \
  88. { \
  89. struct funcdesc_value fv = { \
  90. (void*)((SYMBOL) + *(REL)), \
  91. (LOAD).got_value \
  92. }; \
  93. *(struct funcdesc_value volatile *)(REL) = fv; \
  94. break; \
  95. } \
  96. default: \
  97. _dl_exit(1); \
  98. }
  99. /*
  100. * Transfer control to the user's application, once the dynamic loader
  101. * is done. We return the address of the function's entry point to
  102. * _dl_boot, see boot1_arch.h.
  103. */
  104. #define START() do { \
  105. struct elf_resolve *exec_mod = _dl_loaded_modules; \
  106. dl_main_funcdesc->entry_point = _dl_elf_main; \
  107. while (exec_mod->libtype != elf_executable) \
  108. exec_mod = exec_mod->next; \
  109. dl_main_funcdesc->got_value = exec_mod->loadaddr.got_value; \
  110. return; \
  111. } while (0)