dl-startup.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /* Copyright (C) 2010 Texas Instruments Incorporated
  2. * Contributed by Mark Salter <msalter@redhat.com>
  3. *
  4. * Borrowed heavily from frv arch:
  5. * Copyright (C) 2003 Red Hat, Inc.
  6. *
  7. * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  8. */
  9. #undef DL_START
  10. #define DL_START(X) \
  11. int \
  12. _dl_start (unsigned placeholder, \
  13. struct elf32_dsbt_loadmap *dl_boot_progmap, \
  14. struct elf32_dsbt_loadmap *dl_boot_ldsomap, \
  15. Elf32_Dyn *dl_boot_ldso_dyn_pointer, \
  16. X)
  17. /*
  18. * On entry, the kernel has set up the stack thusly:
  19. *
  20. * 0(sp) pad0
  21. * 4(sp) pad1
  22. * 8(sp) argc
  23. * 12(sp) argv[0]
  24. * ...
  25. * (4*(argc+3))(sp) NULL
  26. * (4*(argc+4))(sp) envp[0]
  27. * ...
  28. * NULL
  29. *
  30. * Register values are unspecified, except:
  31. *
  32. * B4 --> executable loadmap address
  33. * A6 --> interpreter loadmap address
  34. * B6 --> dynamic section address
  35. * B14 --> our DP setup by kernel
  36. *
  37. * NB: DSBT index is always 0 for the executable
  38. * and 1 for the interpreter
  39. */
  40. __asm__(" .text\n"
  41. ".globl _start\n"
  42. "_start:\n"
  43. " B .S2 _dl_start\n"
  44. " STW .D2T2 B14, *+B14[1]\n"
  45. " ADD .D1X B15,8,A8\n"
  46. " ADDKPC .S2 ret_from_dl,B3,2\n"
  47. "ret_from_dl:\n"
  48. " B .S2X A4\n"
  49. " || LDW .D2T2 *+B14[0],B14\n"
  50. " ADDKPC .S2 __dl_fini,B0,0\n"
  51. " MV .S1X B0,A4\n"
  52. " NOP\n"
  53. " NOP\n"
  54. " NOP\n"
  55. "__dl_fini:\n"
  56. " LDW .D2T2 *+B14[1],B14\n"
  57. " NOP 4\n"
  58. " LDW .D2T1 *+B14($GOT(_dl_fini)), A0\n"
  59. " NOP 4\n"
  60. " BNOP .S2X A0, 5\n");
  61. __asm__(" .text\n"
  62. "__c6x_cache_sync:\n"
  63. " MVK .S2 330,B0\n"
  64. " SWE\n"
  65. " NOP\n"
  66. " BNOP .S2 B3,5\n"
  67. " NOP\n"
  68. " NOP\n"
  69. " NOP\n"
  70. " NOP\n"
  71. "\n"
  72. );
  73. /*
  74. * Get a pointer to the argv array. On many platforms this can be just
  75. * the address of the first argument, on other platforms we need to
  76. * do something a little more subtle here.
  77. */
  78. #define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long*) ARGS) + 1)
  79. struct elf32_dsbt_loadmap;
  80. /*
  81. * Here is a macro to perform a relocation. This is only used when
  82. * bootstrapping the dynamic loader. RELP is the relocation that we
  83. * are performing, REL is the pointer to the address we are relocating.
  84. * SYMBOL is the symbol involved in the relocation, and LOAD is the
  85. * load address.
  86. */
  87. #define PERFORM_BOOTSTRAP_RELOC(RELP,REL,SYMBOL,LOAD,SYMTAB) \
  88. switch(ELF32_R_TYPE((RELP)->r_info)){ \
  89. case R_C6000_ABS_L16: \
  90. { \
  91. unsigned int opcode = *(REL); \
  92. unsigned int v = (SYMBOL) + (RELP)->r_addend; \
  93. opcode &= ~0x7fff80; \
  94. opcode |= ((v & 0xffff) << 7); \
  95. *(REL) = opcode; \
  96. } \
  97. break; \
  98. case R_C6000_ABS_H16: \
  99. { \
  100. unsigned int opcode = *(REL); \
  101. unsigned int v = (SYMBOL) + (RELP)->r_addend; \
  102. opcode &= ~0x7fff80; \
  103. opcode |= ((v >> 9) & 0x7fff80); \
  104. *(REL) = opcode; \
  105. } \
  106. break; \
  107. case R_C6000_ABS32: \
  108. *(REL) = (SYMBOL) + (RELP)->r_addend; \
  109. break; \
  110. default: \
  111. _dl_exit(1); \
  112. }
  113. extern void __c6x_cache_sync(unsigned long start, unsigned long end)
  114. attribute_hidden;