dl-sysdep.h 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /* Copyright (C) 2003, 2004 Red Hat, Inc.
  2. * Contributed by Alexandre Oliva <aoliva@redhat.com>
  3. * Based on ../i386/dl-sysdep.h
  4. *
  5. * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  6. */
  7. /*
  8. * Various assembly language/system dependent hacks that are required
  9. * so that we can minimize the amount of platform specific code.
  10. */
  11. /*
  12. * Define this if the system uses RELOCA.
  13. */
  14. #undef ELF_USES_RELOCA
  15. /* JMPREL relocs are inside the DT_RELA table. */
  16. #define ELF_MACHINE_PLTREL_OVERLAP
  17. #define DL_NO_COPY_RELOCS
  18. /*
  19. * Initialization sequence for a GOT. Copy the resolver function
  20. * descriptor and the pointer to the elf_resolve/link_map data
  21. * structure. Initialize the got_value in the module while at that.
  22. */
  23. #define INIT_GOT(GOT_BASE,MODULE) \
  24. { \
  25. (MODULE)->loadaddr.got_value = (GOT_BASE); \
  26. GOT_BASE[0] = ((unsigned long *)&_dl_linux_resolve)[0]; \
  27. GOT_BASE[1] = ((unsigned long *)&_dl_linux_resolve)[1]; \
  28. GOT_BASE[2] = (unsigned long) MODULE; \
  29. }
  30. /* Here we define the magic numbers that this dynamic loader should accept */
  31. #define MAGIC1 EM_CYGNUS_FRV
  32. #undef MAGIC2
  33. /* Used for error messages */
  34. #define ELF_TARGET "FR-V"
  35. struct elf_resolve;
  36. struct funcdesc_value
  37. {
  38. void *entry_point;
  39. void *got_value;
  40. } __attribute__((__aligned__(8)));
  41. extern int _dl_linux_resolve(void) __attribute__((__visibility__("hidden")));
  42. struct funcdesc_ht;
  43. /* We must force strings used early in the bootstrap into the data
  44. segment, such that they are referenced with GOTOFF instead of
  45. GPREL, because GPREL needs the GOT to have already been
  46. relocated. */
  47. #undef SEND_EARLY_STDERR
  48. #define SEND_EARLY_STDERR(S) \
  49. do { static char __s[] = (S); SEND_STDERR (__s); } while (0)
  50. #define DL_LOADADDR_TYPE struct elf32_fdpic_loadaddr
  51. #define DL_RELOC_ADDR(ADDR, LOADADDR) \
  52. (__reloc_pointer ((void*)(ADDR), (LOADADDR).map))
  53. #define DL_ADDR_TO_FUNC_PTR(ADDR, LOADADDR) \
  54. ((void(*)(void)) _dl_funcdesc_for ((void*)(ADDR), (LOADADDR).got_value))
  55. #define _dl_stabilize_funcdesc(val) \
  56. ({ __asm__ ("" : "+m" (*(val))); (val); })
  57. #define DL_CALL_FUNC_AT_ADDR(ADDR, LOADADDR, SIGNATURE, ...) \
  58. ({ struct funcdesc_value fd = { (void*)(ADDR), (LOADADDR).got_value }; \
  59. void (*pf)(void) = (void*) _dl_stabilize_funcdesc (&fd); \
  60. (* SIGNATURE pf)(__VA_ARGS__); })
  61. #define DL_INIT_LOADADDR_BOOT(LOADADDR, BASEADDR) \
  62. (__dl_init_loadaddr_map (&(LOADADDR), dl_boot_got_pointer, \
  63. dl_boot_ldsomap ?: dl_boot_progmap))
  64. #define DL_INIT_LOADADDR_PROG(LOADADDR, BASEADDR) \
  65. (__dl_init_loadaddr_map (&(LOADADDR), 0, dl_boot_progmap))
  66. #define DL_INIT_LOADADDR_EXTRA_DECLS \
  67. int dl_init_loadaddr_load_count;
  68. #define DL_INIT_LOADADDR(LOADADDR, BASEADDR, PHDR, PHDRCNT) \
  69. (dl_init_loadaddr_load_count = \
  70. __dl_init_loadaddr (&(LOADADDR), (PHDR), (PHDRCNT)))
  71. #define DL_INIT_LOADADDR_HDR(LOADADDR, ADDR, PHDR) \
  72. (__dl_init_loadaddr_hdr ((LOADADDR), (ADDR), (PHDR), \
  73. dl_init_loadaddr_load_count))
  74. #define DL_LOADADDR_UNMAP(LOADADDR, LEN) \
  75. (__dl_loadaddr_unmap ((LOADADDR), (NULL)))
  76. #define DL_LIB_UNMAP(LIB, LEN) \
  77. (__dl_loadaddr_unmap ((LIB)->loadaddr, (LIB)->funcdesc_ht))
  78. #define DL_LOADADDR_BASE(LOADADDR) \
  79. ((LOADADDR).got_value)
  80. /* This is called from dladdr(), such that we map a function
  81. descriptor's address to the function's entry point before trying to
  82. find in which library it's defined. */
  83. #define DL_LOOKUP_ADDRESS(ADDRESS) (_dl_lookup_address (ADDRESS))
  84. #define DL_ADDR_IN_LOADADDR(ADDR, TPNT, TFROM) \
  85. (! (TFROM) && __dl_addr_in_loadaddr ((void*)(ADDR), (TPNT)->loadaddr))
  86. /* Make sure we only load libraries that use the same number of
  87. general-purpose and floating-point registers the dynamic loader was
  88. compiled for. */
  89. #define DL_CHECK_REG_COUNT(flags) \
  90. (((flags & EF_FRV_GPR_MASK) == EF_FRV_GPR_32 ? __FRV_GPR__ == 32 : 1) \
  91. && ((flags & EF_FRV_GPR_MASK) == EF_FRV_GPR_64 ? __FRV_GPR__ == 64 : 1) \
  92. && ((flags & EF_FRV_FPR_MASK) == EF_FRV_FPR_32 ? __FRV_FPR__ == 32 : 1) \
  93. && ((flags & EF_FRV_FPR_MASK) == EF_FRV_FPR_64 ? __FRV_FPR__ == 64 : 1) \
  94. && ((flags & EF_FRV_FPR_MASK) == EF_FRV_FPR_NONE ? __FRV_FPR__ == 0 : 1))
  95. /* We only support loading FDPIC independently-relocatable shared
  96. libraries. It probably wouldn't be too hard to support loading
  97. shared libraries that require relocation by the same amount, but we
  98. don't know that they exist or would be useful, and the dynamic
  99. loader code could leak the whole-library map unless we keeping a
  100. bit more state for DL_LOADADDR_UNMAP and DL_LIB_UNMAP, so let's
  101. keep things simple for now. */
  102. #define DL_CHECK_LIB_TYPE(epnt, piclib, _dl_progname, libname) \
  103. do \
  104. { \
  105. if (((epnt)->e_flags & EF_FRV_FDPIC) && ! ((epnt)->e_flags & EF_FRV_PIC)) \
  106. (piclib) = 2; \
  107. else \
  108. { \
  109. _dl_internal_error_number = LD_ERROR_NOTDYN; \
  110. _dl_dprintf(2, "%s: '%s' is not an FDPIC shared library" \
  111. "\n", (_dl_progname), (libname)); \
  112. _dl_close(infile); \
  113. return NULL; \
  114. } \
  115. \
  116. if (! DL_CHECK_REG_COUNT ((epnt)->e_flags)) \
  117. { \
  118. _dl_internal_error_number = LD_ERROR_NOTDYN; \
  119. _dl_dprintf(2, "%s: '%s' assumes different register counts" \
  120. "\n", (_dl_progname), (libname)); \
  121. _dl_close(infile); \
  122. } \
  123. } \
  124. while (0)
  125. /* We want want to apply all relocations in the interpreter during
  126. bootstrap. Because of this, we have to skip the interpreter
  127. relocations in _dl_parse_relocation_information(), see
  128. elfinterp.c. */
  129. #define DL_SKIP_BOOTSTRAP_RELOC(SYMTAB, INDEX, STRTAB) 0
  130. #ifdef __NR_pread
  131. #define _DL_PREAD(FD, BUF, SIZE, OFFSET) \
  132. (_dl_pread((FD), (BUF), (SIZE), (OFFSET)))
  133. #endif
  134. /* We want to return to dlsym() a function descriptor if the symbol
  135. turns out to be a function. */
  136. #define DL_FIND_HASH_VALUE(TPNT, TYPE_CLASS, SYM) \
  137. (((TYPE_CLASS) & ELF_RTYPE_CLASS_DLSYM) \
  138. && ELF32_ST_TYPE((SYM)->st_info) == STT_FUNC \
  139. ? _dl_funcdesc_for (DL_RELOC_ADDR ((SYM)->st_value, (TPNT)->loadaddr), \
  140. (TPNT)->loadaddr.got_value) \
  141. : DL_RELOC_ADDR ((SYM)->st_value, (TPNT)->loadaddr))
  142. #define DL_GET_READY_TO_RUN_EXTRA_PARMS \
  143. , struct elf32_fdpic_loadmap *dl_boot_progmap
  144. #define DL_GET_READY_TO_RUN_EXTRA_ARGS \
  145. , dl_boot_progmap
  146. #ifdef __USE_GNU
  147. # include <link.h>
  148. #else
  149. # define __USE_GNU
  150. # include <link.h>
  151. # undef __USE_GNU
  152. #endif