dl-sysdep.h 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  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. /* We must force strings used early in the bootstrap into the text
  41. segment (const data), such that they are referenced relative to
  42. the DP register rather than through the GOT which will not have
  43. been relocated when these are used. */
  44. #undef SEND_EARLY_STDERR
  45. #define SEND_EARLY_STDERR(S) \
  46. do { static char __s[] = (S); SEND_STDERR (__s); } 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->dsbt_table)
  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. * Compute the GOT address.
  120. * Also setup program and interpreter DSBT table entries.
  121. */
  122. #define DL_BOOT_COMPUTE_GOT(GOT) \
  123. do { \
  124. unsigned long *ldso_dsbt, *prog_dsbt; \
  125. ldso_dsbt = dl_boot_ldsomap->dsbt_table; \
  126. prog_dsbt = dl_boot_progmap->dsbt_table; \
  127. ldso_dsbt[0] = prog_dsbt[0] = (unsigned long)prog_dsbt; \
  128. ldso_dsbt[1] = prog_dsbt[1] = (unsigned long)ldso_dsbt; \
  129. (GOT) = ldso_dsbt + dl_boot_ldsomap->dsbt_size; \
  130. } while(0)
  131. #define DL_BOOT_COMPUTE_DYN(dpnt, got, load_addr) \
  132. ((dpnt) = dl_boot_ldso_dyn_pointer)
  133. #ifdef __USE_GNU
  134. # include <link.h>
  135. #else
  136. # define __USE_GNU
  137. # include <link.h>
  138. # undef __USE_GNU
  139. #endif
  140. static __always_inline Elf32_Addr
  141. elf_machine_load_address (void)
  142. {
  143. /* this is never an issue on DSBT systems */
  144. return 0;
  145. }
  146. static __always_inline void
  147. elf_machine_relative (DL_LOADADDR_TYPE load_off, const Elf32_Addr rel_addr,
  148. Elf32_Word relative_count)
  149. {
  150. }
  151. /* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so
  152. PLT entries should not be allowed to define the value.
  153. ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
  154. of the main executable's symbols, as for a COPY reloc. */
  155. #define elf_machine_type_class(type) \
  156. ((((type) == R_C6000_JUMP_SLOT) * ELF_RTYPE_CLASS_PLT) \
  157. | (((type) == R_C6000_COPY) * ELF_RTYPE_CLASS_COPY))
  158. #define ARCH_NUM 3
  159. #define DT_DSBT_BASE_IDX (DT_NUM + OS_NUM)
  160. #define DT_DSBT_SIZE_IDX (DT_NUM + OS_NUM + 1)
  161. #define DT_DSBT_INDEX_IDX (DT_NUM + OS_NUM + 2)
  162. #define ARCH_DYNAMIC_INFO(dpnt, dynamic, debug_addr) \
  163. do { \
  164. if (dpnt->d_tag == DT_C6000_DSBT_BASE) \
  165. dynamic[DT_DSBT_BASE_IDX] = dpnt->d_un.d_val; \
  166. else if (dpnt->d_tag == DT_C6000_DSBT_SIZE) \
  167. dynamic[DT_DSBT_SIZE_IDX] = dpnt->d_un.d_val; \
  168. else if (dpnt->d_tag == DT_C6000_DSBT_INDEX) \
  169. dynamic[DT_DSBT_INDEX_IDX] = dpnt->d_un.d_val; \
  170. } while (0)