dl-sysdep.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  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, 2004 Red Hat, Inc.
  6. *
  7. * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  8. */
  9. #include <bits/elf-dsbt.h>
  10. /*
  11. * Define this if the system uses RELOCA.
  12. */
  13. #define ELF_USES_RELOCA 1
  14. /* JMPREL relocs are inside the DT_RELA table. */
  15. /* Actually looks like a linker bug sets DT_JMPREL anyway */
  16. #define ELF_MACHINE_PLTREL_OVERLAP 1
  17. #undef DL_NO_COPY_RELOCS
  18. #define HAVE_DL_INLINES_H
  19. /*
  20. * Various assembly language/system dependent hacks that are required
  21. * so that we can minimize the amount of platform specific code.
  22. */
  23. /* Initialization sequence for the GOT. */
  24. #define INIT_GOT(GOT_BASE,MODULE) \
  25. { \
  26. GOT_BASE[0] = (unsigned long) _dl_linux_resolve; \
  27. GOT_BASE[1] = (unsigned long) MODULE; \
  28. }
  29. /* Here we define the magic numbers that this dynamic loader should accept */
  30. #define MAGIC1 EM_TI_C6000
  31. #undef MAGIC2
  32. /* Used for error messages */
  33. #define ELF_TARGET "C6000"
  34. /* Need bootstrap relocations */
  35. #define ARCH_NEEDS_BOOTSTRAP_RELOCS
  36. struct elf_resolve;
  37. extern int _dl_linux_resolve(void) attribute_hidden;
  38. struct funcdesc_ht;
  39. struct elf32_dsbt_loadaddr;
  40. /* Current toolchains access constant strings via unrelocated GOT
  41. entries. Fortunately, we have enough in place to just call the
  42. relocation function early on. */
  43. #undef SEND_EARLY_STDERR
  44. #define SEND_EARLY_STDERR(S) \
  45. do { char *__p = __reloc_pointer((S), dl_boot_ldsomap?:dl_boot_progmap);\
  46. SEND_STDERR (__p); } while (0)
  47. #define DL_LOADADDR_TYPE struct elf32_dsbt_loadaddr
  48. #define DL_RELOC_ADDR(LOADADDR, ADDR) \
  49. ((ElfW(Addr))__reloc_pointer ((void*)(ADDR), (LOADADDR).map))
  50. #define DL_INIT_LOADADDR_BOOT(LOADADDR, BASEADDR) \
  51. do { \
  52. struct elf32_dsbt_loadmap *map; \
  53. map = dl_boot_ldsomap ?: dl_boot_progmap; \
  54. if (map->version != 0) { \
  55. SEND_EARLY_STDERR ("Invalid loadmap version number\n"); \
  56. _dl_exit(-1); \
  57. } \
  58. if (map->nsegs < 2) { \
  59. SEND_EARLY_STDERR ("Invalid segment count in loadmap\n"); \
  60. _dl_exit(-1); \
  61. } \
  62. (LOADADDR).map = map; \
  63. } while(0)
  64. #define DL_INIT_LOADADDR_PROG(LOADADDR, BASEADDR) \
  65. do { \
  66. if (dl_boot_progmap->version != 0) { \
  67. SEND_EARLY_STDERR ("Invalid loadmap version number\n"); \
  68. _dl_exit(-1); \
  69. } \
  70. if (dl_boot_progmap->nsegs < 2) { \
  71. SEND_EARLY_STDERR ("Invalid segment count in loadmap\n"); \
  72. _dl_exit(-1); \
  73. } \
  74. (LOADADDR).map = dl_boot_progmap; \
  75. } while(0)
  76. #define DL_INIT_LOADADDR_EXTRA_DECLS \
  77. int dl_init_loadaddr_load_count;
  78. #define DL_INIT_LOADADDR(LOADADDR, BASEADDR, PHDR, PHDRCNT) \
  79. (dl_init_loadaddr_load_count = \
  80. __dl_init_loadaddr (&(LOADADDR), (PHDR), (PHDRCNT)))
  81. #define DL_INIT_LOADADDR_HDR(LOADADDR, ADDR, PHDR) \
  82. (__dl_init_loadaddr_hdr ((LOADADDR), (ADDR), (PHDR), \
  83. dl_init_loadaddr_load_count))
  84. #define DL_UPDATE_LOADADDR_HDR(LOADADDR, ADDR, PHDR) \
  85. (__dl_update_loadaddr_hdr ((LOADADDR), (ADDR), (PHDR)))
  86. #define DL_LOADADDR_UNMAP(LOADADDR, LEN) \
  87. (__dl_loadaddr_unmap ((LOADADDR)))
  88. #define DL_LIB_UNMAP(LIB, LEN) \
  89. (__dl_loadaddr_unmap ((LIB)->loadaddr))
  90. #define DL_LOADADDR_BASE(LOADADDR) \
  91. ((LOADADDR).map)
  92. #define DL_ADDR_IN_LOADADDR(ADDR, TPNT, TFROM) \
  93. (! (TFROM) && __dl_addr_in_loadaddr ((void*)(ADDR), (TPNT)->loadaddr))
  94. /* We only support loading DSBT relocatable shared libraries.
  95. It probably wouldn't be too hard to support loading statically
  96. linked executables that require relocation.*/
  97. #define DL_CHECK_LIB_TYPE(epnt, piclib, _dl_progname, libname) \
  98. do \
  99. { \
  100. (piclib) = 2; \
  101. } \
  102. while (0)
  103. /* We want want to apply all relocations in the interpreter during
  104. bootstrap. Because of this, we have to skip the interpreter
  105. relocations in _dl_parse_relocation_information(), see
  106. elfinterp.c. */
  107. #define DL_SKIP_BOOTSTRAP_RELOC(SYMTAB, INDEX, STRTAB) 0
  108. #ifdef __NR_pread64
  109. #define _DL_PREAD(FD, BUF, SIZE, OFFSET) \
  110. (_dl_pread((FD), (BUF), (SIZE), (OFFSET)))
  111. #endif
  112. #define DL_GET_READY_TO_RUN_EXTRA_PARMS \
  113. , struct elf32_dsbt_loadmap *dl_boot_progmap \
  114. , struct elf32_dsbt_loadmap *dl_boot_ldsomap
  115. #define DL_GET_READY_TO_RUN_EXTRA_ARGS \
  116. , dl_boot_progmap \
  117. , dl_boot_ldsomap
  118. /*
  119. * C6X doesn't really need the GOT here.
  120. * The GOT is placed just past the DSBT table, so we could find it by
  121. * using the DSBT register + table size found in the dynamic section.
  122. *
  123. * do { \
  124. * unsigned long *ldso_dsbt; \
  125. * ElfW(Dyn) *d = dl_boot_ldso_dyn_pointer; \
  126. * while (d->d_tag != DT_NULL) { \
  127. * if (d->d_tag == DT_C6000_DSBT_SIZE) { \
  128. * __asm__ (" MV .S2 B14,%0\n" \
  129. * : "=b" (ldso_dsbt)); \
  130. * (GOT) = ldso_dsbt + d->d_un.d_val; \
  131. * break; \
  132. * } \
  133. * d++; \
  134. * } \
  135. * } while(0)
  136. *
  137. * Instead, just point it to the DSBT table to avoid unused variable warning.
  138. */
  139. #define DL_BOOT_COMPUTE_GOT(GOT) \
  140. __asm__ (" MV .S2 B14,%0\n" : "=b" (GOT))
  141. #define DL_BOOT_COMPUTE_DYN(dpnt, got, load_addr) \
  142. ((dpnt) = dl_boot_ldso_dyn_pointer)
  143. /* Define this to declare the library offset. */
  144. #define DL_DEF_LIB_OFFSET
  145. /* Define this to get the library offset. */
  146. #define DL_GET_LIB_OFFSET() 0
  147. /* Define this to set the library offset. */
  148. #define DL_SET_LIB_OFFSET(offset)
  149. /* Define this to get the real object's runtime address. */
  150. #define DL_GET_RUN_ADDR(loadaddr, mapaddr) (loadaddr)
  151. #ifdef __USE_GNU
  152. # include <link.h>
  153. #else
  154. # define __USE_GNU
  155. # include <link.h>
  156. # undef __USE_GNU
  157. #endif
  158. /* we need this for __LDSO_STANDALONE_SUPPORT__ */
  159. #define elf_machine_load_address() \
  160. (dl_boot_ldsomap ?: dl_boot_progmap)->segs[0].addr
  161. static __always_inline void
  162. elf_machine_relative (DL_LOADADDR_TYPE load_off, const Elf32_Addr rel_addr,
  163. Elf32_Word relative_count)
  164. {
  165. }
  166. /* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so
  167. PLT entries should not be allowed to define the value.
  168. ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
  169. of the main executable's symbols, as for a COPY reloc. */
  170. #define elf_machine_type_class(type) \
  171. ((((type) == R_C6000_JUMP_SLOT) * ELF_RTYPE_CLASS_PLT) \
  172. | (((type) == R_C6000_COPY) * ELF_RTYPE_CLASS_COPY))
  173. #define ARCH_NUM 3
  174. #define DT_DSBT_BASE_IDX (DT_NUM + OS_NUM)
  175. #define DT_DSBT_SIZE_IDX (DT_NUM + OS_NUM + 1)
  176. #define DT_DSBT_INDEX_IDX (DT_NUM + OS_NUM + 2)
  177. #define ARCH_DYNAMIC_INFO(dpnt, dynamic, debug_addr) \
  178. do { \
  179. if (dpnt->d_tag == DT_C6000_DSBT_BASE) \
  180. dynamic[DT_DSBT_BASE_IDX] = dpnt->d_un.d_val; \
  181. else if (dpnt->d_tag == DT_C6000_DSBT_SIZE) \
  182. dynamic[DT_DSBT_SIZE_IDX] = dpnt->d_un.d_val; \
  183. else if (dpnt->d_tag == DT_C6000_DSBT_INDEX) \
  184. dynamic[DT_DSBT_INDEX_IDX] = dpnt->d_un.d_val; \
  185. } while (0)