ld_sysdep.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /*
  2. * Various assmbly language/system dependent hacks that are required
  3. * so that we can minimize the amount of platform specific code.
  4. */
  5. /*
  6. * Define this if the system uses RELOCA.
  7. */
  8. #define ELF_USES_RELOCA
  9. /*
  10. * Get a pointer to the argv array. On many platforms this can be just
  11. * the address if the first argument, on other platforms we need to
  12. * do something a little more subtle here.
  13. */
  14. #define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long*) ARGS)+1)
  15. /*
  16. * Initialization sequence for a GOT.
  17. */
  18. #define INIT_GOT(GOT_BASE,MODULE) _dl_init_got(GOT_BASE,MODULE)
  19. /* Stuff for the PLT. */
  20. #define PLT_INITIAL_ENTRY_WORDS 18
  21. #define PLT_LONGBRANCH_ENTRY_WORDS 0
  22. #define PLT_TRAMPOLINE_ENTRY_WORDS 6
  23. #define PLT_DOUBLE_SIZE (1<<13)
  24. #define PLT_ENTRY_START_WORDS(entry_number) \
  25. (PLT_INITIAL_ENTRY_WORDS + (entry_number)*2 \
  26. + ((entry_number) > PLT_DOUBLE_SIZE \
  27. ? ((entry_number) - PLT_DOUBLE_SIZE)*2 \
  28. : 0))
  29. #define PLT_DATA_START_WORDS(num_entries) PLT_ENTRY_START_WORDS(num_entries)
  30. /* Macros to build PowerPC opcode words. */
  31. #define OPCODE_ADDI(rd,ra,simm) \
  32. (0x38000000 | (rd) << 21 | (ra) << 16 | ((simm) & 0xffff))
  33. #define OPCODE_ADDIS(rd,ra,simm) \
  34. (0x3c000000 | (rd) << 21 | (ra) << 16 | ((simm) & 0xffff))
  35. #define OPCODE_ADD(rd,ra,rb) \
  36. (0x7c000214 | (rd) << 21 | (ra) << 16 | (rb) << 11)
  37. #define OPCODE_B(target) (0x48000000 | ((target) & 0x03fffffc))
  38. #define OPCODE_BA(target) (0x48000002 | ((target) & 0x03fffffc))
  39. #define OPCODE_BCTR() 0x4e800420
  40. #define OPCODE_LWZ(rd,d,ra) \
  41. (0x80000000 | (rd) << 21 | (ra) << 16 | ((d) & 0xffff))
  42. #define OPCODE_LWZU(rd,d,ra) \
  43. (0x84000000 | (rd) << 21 | (ra) << 16 | ((d) & 0xffff))
  44. #define OPCODE_MTCTR(rd) (0x7C0903A6 | (rd) << 21)
  45. #define OPCODE_RLWINM(ra,rs,sh,mb,me) \
  46. (0x54000000 | (rs) << 21 | (ra) << 16 | (sh) << 11 | (mb) << 6 | (me) << 1)
  47. #define OPCODE_LI(rd,simm) OPCODE_ADDI(rd,0,simm)
  48. #define OPCODE_ADDIS_HI(rd,ra,value) \
  49. OPCODE_ADDIS(rd,ra,((value) + 0x8000) >> 16)
  50. #define OPCODE_LIS_HI(rd,value) OPCODE_ADDIS_HI(rd,0,value)
  51. #define OPCODE_SLWI(ra,rs,sh) OPCODE_RLWINM(ra,rs,sh,0,31-sh)
  52. #define PPC_DCBST(where) asm volatile ("dcbst 0,%0" : : "r"(where) : "memory")
  53. #define PPC_SYNC asm volatile ("sync" : : : "memory")
  54. #define PPC_ISYNC asm volatile ("sync; isync" : : : "memory")
  55. #define PPC_ICBI(where) asm volatile ("icbi 0,%0" : : "r"(where) : "memory")
  56. #define PPC_DIE asm volatile ("tweq 0,0")
  57. /*
  58. * Here is a macro to perform a relocation. This is only used when
  59. * bootstrapping the dynamic loader. RELP is the relocation that we
  60. * are performing, REL is the pointer to the address we are relocating.
  61. * SYMBOL is the symbol involved in the relocation, and LOAD is the
  62. * load address.
  63. */
  64. #define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \
  65. {int type=ELF32_R_TYPE((RELP)->r_info); \
  66. Elf32_Addr finaladdr=(SYMBOL)+(RELP)->r_addend;\
  67. if (type==R_PPC_RELATIVE) { \
  68. *REL=(Elf32_Word)(LOAD)+(RELP)->r_addend;\
  69. } else if (type==R_PPC_JMP_SLOT) { \
  70. Elf32_Sword delta=finaladdr-(Elf32_Word)(REL);\
  71. *REL=OPCODE_B(delta); \
  72. } else if (type==R_PPC_ADDR32) { \
  73. *REL=finaladdr; \
  74. } else { \
  75. _dl_exit(100+ELF32_R_TYPE((RELP)->r_info)); \
  76. } \
  77. PPC_DCBST(REL); PPC_SYNC; PPC_ICBI(REL); \
  78. }
  79. /*
  80. * Transfer control to the user's application, once the dynamic loader
  81. * is done. This routine has to exit the current function, then
  82. * call the _dl_elf_main function.
  83. */
  84. /* hgb@ifi.uio.no:
  85. * Adding a clobber list consisting of r0 for %1. addi on PowerPC
  86. * takes a register as the second argument, but if the register is
  87. * r0, the value 0 is used instead. If r0 is used here, the stack
  88. * pointer (r1) will be zeroed, and the dynamically linked
  89. * application will seg.fault immediatly when receiving control.
  90. */
  91. #define START() \
  92. __asm__ volatile ( \
  93. "addi 1,%1,0\n\t" \
  94. "mtlr %0\n\t" \
  95. "blrl\n\t" \
  96. : : "r" (_dl_elf_main), "r" (args) \
  97. : "r0")
  98. /* Here we define the magic numbers that this dynamic loader should accept */
  99. #define MAGIC1 EM_PPC
  100. #undef MAGIC2
  101. /* Used for error messages */
  102. #define ELF_TARGET "powerpc"
  103. struct elf_resolve;
  104. extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
  105. void _dl_init_got(unsigned long *lpnt,struct elf_resolve *tpnt);
  106. #define do_rem(result, n, base) result = (n % base)
  107. /* 4096 bytes alignment */
  108. #define PAGE_ALIGN 0xfffff000
  109. #define ADDR_ALIGN 0xfff
  110. #define OFFS_ALIGN 0x7ffff000