dl-sysdep.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /* vi: set sw=8 ts=8: */
  2. /*
  3. * Various assmbly language/system dependent hacks that are required
  4. * so that we can minimize the amount of platform specific code.
  5. */
  6. /* Define this if the system uses RELOCA. */
  7. #undef ELF_USES_RELOCA
  8. #include <elf.h>
  9. #include <link.h>
  10. #define ARCH_NUM 3
  11. #define DT_MIPS_GOTSYM_IDX (DT_NUM + OS_NUM)
  12. #define DT_MIPS_LOCAL_GOTNO_IDX (DT_NUM + OS_NUM +1)
  13. #define DT_MIPS_SYMTABNO_IDX (DT_NUM + OS_NUM +2)
  14. #define ARCH_DYNAMIC_INFO(dpnt, dynamic, debug_addr) \
  15. do { \
  16. if (dpnt->d_tag == DT_MIPS_GOTSYM) \
  17. dynamic[DT_MIPS_GOTSYM_IDX] = dpnt->d_un.d_val; \
  18. else if(dpnt->d_tag == DT_MIPS_LOCAL_GOTNO) \
  19. dynamic[DT_MIPS_LOCAL_GOTNO_IDX] = dpnt->d_un.d_val; \
  20. else if(dpnt->d_tag == DT_MIPS_SYMTABNO) \
  21. dynamic[DT_MIPS_SYMTABNO_IDX] = dpnt->d_un.d_val; \
  22. else if (dpnt->d_tag == DT_MIPS_RLD_MAP) \
  23. *(Elf32_Addr *)(dpnt->d_un.d_ptr) = (Elf32_Addr) debug_addr; \
  24. } while (0)
  25. /* Initialization sequence for the application/library GOT. */
  26. #define INIT_GOT(GOT_BASE,MODULE) \
  27. do { \
  28. unsigned long i; \
  29. \
  30. /* Check if this is the dynamic linker itself */ \
  31. if (MODULE->libtype == program_interpreter) \
  32. continue; \
  33. \
  34. /* Fill in first two GOT entries according to the ABI */ \
  35. GOT_BASE[0] = (unsigned long) _dl_runtime_resolve; \
  36. GOT_BASE[1] = (unsigned long) MODULE; \
  37. \
  38. /* Add load address displacement to all local GOT entries */ \
  39. i = 2; \
  40. while (i < MODULE->dynamic_info[DT_MIPS_LOCAL_GOTNO_IDX]) \
  41. GOT_BASE[i++] += (unsigned long) MODULE->loadaddr; \
  42. \
  43. } while (0)
  44. /* Here we define the magic numbers that this dynamic loader should accept */
  45. #define MAGIC1 EM_MIPS
  46. #define MAGIC2 EM_MIPS_RS3_LE
  47. /* Used for error messages */
  48. #define ELF_TARGET "MIPS"
  49. unsigned long __dl_runtime_resolve(unsigned long sym_index,
  50. unsigned long old_gpreg);
  51. struct elf_resolve;
  52. void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt, int lazy);
  53. #define do_rem(result, n, base) ((result) = (n) % (base))
  54. /* 4096 bytes alignment */
  55. #define PAGE_ALIGN 0xfffff000
  56. #define ADDR_ALIGN 0xfff
  57. #define OFFS_ALIGN 0x7ffff000
  58. #define elf_machine_type_class(type) ELF_RTYPE_CLASS_PLT
  59. /* MIPS does not have COPY relocs */
  60. #define DL_NO_COPY_RELOCS
  61. #define OFFSET_GP_GOT 0x7ff0
  62. static inline ElfW(Addr) *
  63. elf_mips_got_from_gpreg (ElfW(Addr) gpreg)
  64. {
  65. /* FIXME: the offset of gp from GOT may be system-dependent. */
  66. return (ElfW(Addr) *) (gpreg - OFFSET_GP_GOT);
  67. }
  68. /* Return the link-time address of _DYNAMIC. Conveniently, this is the
  69. first element of the GOT. This must be inlined in a function which
  70. uses global data. We assume its $gp points to the primary GOT. */
  71. static inline ElfW(Addr)
  72. elf_machine_dynamic (void)
  73. {
  74. register ElfW(Addr) gp __asm__ ("$28");
  75. return *elf_mips_got_from_gpreg (gp);
  76. }
  77. #define STRINGXP(X) __STRING(X)
  78. #define STRINGXV(X) STRINGV_(X)
  79. #define STRINGV_(...) # __VA_ARGS__
  80. #define PTR_LA la
  81. #define PTR_SUBU subu
  82. /* Return the run-time load address of the shared object. */
  83. static inline ElfW(Addr)
  84. elf_machine_load_address (void)
  85. {
  86. ElfW(Addr) addr;
  87. asm (" .set noreorder\n"
  88. " " STRINGXP (PTR_LA) " %0, 0f\n"
  89. " bltzal $0, 0f\n"
  90. " nop\n"
  91. "0: " STRINGXP (PTR_SUBU) " %0, $31, %0\n"
  92. " .set reorder\n"
  93. : "=r" (addr)
  94. : /* No inputs */
  95. : "$31");
  96. return addr;
  97. }
  98. static inline void
  99. elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr,
  100. Elf32_Word relative_count)
  101. {
  102. /* No REALTIVE relocs in MIPS? */
  103. }