dl-elf.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. #ifndef LINUXELF_H
  2. #define LINUXELF_H
  3. #include <dl-string.h> /* before elf.h to get ELF_USES_RELOCA right */
  4. #include <elf.h>
  5. #include <link.h>
  6. /* Forward declarations for stuff defined in ld_hash.h */
  7. struct dyn_elf;
  8. struct elf_resolve;
  9. #include <dl-defs.h>
  10. #ifdef __LDSO_CACHE_SUPPORT__
  11. extern int _dl_map_cache(void);
  12. extern int _dl_unmap_cache(void);
  13. #else
  14. static inline void _dl_map_cache(void) { }
  15. static inline void _dl_unmap_cache(void) { }
  16. #endif
  17. /* Function prototypes for non-static stuff in readelflib1.c */
  18. extern void _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt,
  19. unsigned long rel_addr, unsigned long rel_size);
  20. extern int _dl_parse_relocation_information(struct dyn_elf *rpnt,
  21. unsigned long rel_addr, unsigned long rel_size);
  22. extern struct elf_resolve * _dl_load_shared_library(int secure,
  23. struct dyn_elf **rpnt, struct elf_resolve *tpnt, char *full_libname,
  24. int trace_loaded_objects);
  25. extern struct elf_resolve * _dl_load_elf_shared_library(int secure,
  26. struct dyn_elf **rpnt, char *libname);
  27. extern struct elf_resolve *_dl_check_if_named_library_is_loaded(const char *full_libname,
  28. int trace_loaded_objects);
  29. extern int _dl_linux_resolve(void);
  30. extern int _dl_fixup(struct dyn_elf *rpnt, int flag);
  31. extern void _dl_protect_relro (struct elf_resolve *l);
  32. /*
  33. * Bitsize related settings for things ElfW()
  34. * does not handle already
  35. */
  36. #if __WORDSIZE == 64
  37. # define ELF_ST_BIND(val) ELF64_ST_BIND(val)
  38. # define ELF_ST_TYPE(val) ELF64_ST_TYPE(val)
  39. # define ELF_R_SYM(i) ELF64_R_SYM(i)
  40. # define ELF_R_TYPE(i) ELF64_R_TYPE(i)
  41. # ifndef ELF_CLASS
  42. # define ELF_CLASS ELFCLASS64
  43. # endif
  44. #else
  45. # define ELF_ST_BIND(val) ELF32_ST_BIND(val)
  46. # define ELF_ST_TYPE(val) ELF32_ST_TYPE(val)
  47. # define ELF_R_SYM(i) ELF32_R_SYM(i)
  48. # define ELF_R_TYPE(i) ELF32_R_TYPE(i)
  49. # ifndef ELF_CLASS
  50. # define ELF_CLASS ELFCLASS32
  51. # endif
  52. #endif
  53. /*
  54. * Datatype of a relocation on this platform
  55. */
  56. #ifdef ELF_USES_RELOCA
  57. # define ELF_RELOC ElfW(Rela)
  58. # define DT_RELOC_TABLE_ADDR DT_RELA
  59. # define DT_RELOC_TABLE_SIZE DT_RELASZ
  60. # define DT_RELOCCOUNT DT_RELACOUNT
  61. # define UNSUPPORTED_RELOC_TYPE DT_REL
  62. # define UNSUPPORTED_RELOC_STR "REL"
  63. #else
  64. # define ELF_RELOC ElfW(Rel)
  65. # define DT_RELOC_TABLE_ADDR DT_REL
  66. # define DT_RELOC_TABLE_SIZE DT_RELSZ
  67. # define DT_RELOCCOUNT DT_RELCOUNT
  68. # define UNSUPPORTED_RELOC_TYPE DT_RELA
  69. # define UNSUPPORTED_RELOC_STR "RELA"
  70. #endif
  71. /* OS and/or GNU dynamic extensions */
  72. #define OS_NUM 1
  73. #define DT_RELCONT_IDX DT_NUM
  74. #ifndef ARCH_DYNAMIC_INFO
  75. /* define in arch specific code, if needed */
  76. # define ARCH_NUM 0
  77. #endif
  78. #define DYNAMIC_SIZE (DT_NUM+OS_NUM+ARCH_NUM)
  79. extern void _dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[], void *debug_addr, ElfW(Addr) load_off);
  80. static __always_inline
  81. void __dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[], void *debug_addr, ElfW(Addr) load_off)
  82. {
  83. for (; dpnt->d_tag; dpnt++) {
  84. if (dpnt->d_tag < DT_NUM) {
  85. dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
  86. #ifndef __mips__
  87. if (dpnt->d_tag == DT_DEBUG)
  88. dpnt->d_un.d_val = (unsigned long)debug_addr;
  89. #endif
  90. if (dpnt->d_tag == DT_BIND_NOW)
  91. dynamic_info[DT_BIND_NOW] = 1;
  92. if (dpnt->d_tag == DT_FLAGS &&
  93. (dpnt->d_un.d_val & DF_BIND_NOW))
  94. dynamic_info[DT_BIND_NOW] = 1;
  95. if (dpnt->d_tag == DT_TEXTREL)
  96. dynamic_info[DT_TEXTREL] = 1;
  97. #ifdef __LDSO_RUNPATH__
  98. if (dpnt->d_tag == DT_RUNPATH)
  99. dynamic_info[DT_RPATH] = 0;
  100. if (dpnt->d_tag == DT_RPATH && dynamic_info[DT_RUNPATH])
  101. dynamic_info[DT_RPATH] = 0;
  102. #endif
  103. } else if (dpnt->d_tag < DT_LOPROC) {
  104. if (dpnt->d_tag == DT_RELOCCOUNT)
  105. dynamic_info[DT_RELCONT_IDX] = dpnt->d_un.d_val;
  106. if (dpnt->d_tag == DT_FLAGS_1 &&
  107. (dpnt->d_un.d_val & DF_1_NOW))
  108. dynamic_info[DT_BIND_NOW] = 1;
  109. }
  110. #ifdef ARCH_DYNAMIC_INFO
  111. else {
  112. ARCH_DYNAMIC_INFO(dpnt, dynamic_info, debug_addr);
  113. }
  114. #endif
  115. }
  116. #define ADJUST_DYN_INFO(tag, load_off) \
  117. do { \
  118. if (dynamic_info[tag]) \
  119. dynamic_info[tag] += load_off; \
  120. } while(0)
  121. ADJUST_DYN_INFO(DT_HASH, load_off);
  122. ADJUST_DYN_INFO(DT_PLTGOT, load_off);
  123. ADJUST_DYN_INFO(DT_STRTAB, load_off);
  124. ADJUST_DYN_INFO(DT_SYMTAB, load_off);
  125. ADJUST_DYN_INFO(DT_RELOC_TABLE_ADDR, load_off);
  126. ADJUST_DYN_INFO(DT_JMPREL, load_off);
  127. #undef ADJUST_DYN_INFO
  128. }
  129. /* Reloc type classes as returned by elf_machine_type_class().
  130. ELF_RTYPE_CLASS_PLT means this reloc should not be satisfied by
  131. some PLT symbol, ELF_RTYPE_CLASS_COPY means this reloc should not be
  132. satisfied by any symbol in the executable. Some architectures do
  133. not support copy relocations. In this case we define the macro to
  134. zero so that the code for handling them gets automatically optimized
  135. out. */
  136. #ifdef DL_NO_COPY_RELOCS
  137. # define ELF_RTYPE_CLASS_COPY (0x0)
  138. #else
  139. # define ELF_RTYPE_CLASS_COPY (0x2)
  140. #endif
  141. #define ELF_RTYPE_CLASS_PLT (0x1)
  142. /* Convert between the Linux flags for page protections and the
  143. ones specified in the ELF standard. */
  144. #define LXFLAGS(X) ( (((X) & PF_R) ? PROT_READ : 0) | \
  145. (((X) & PF_W) ? PROT_WRITE : 0) | \
  146. (((X) & PF_X) ? PROT_EXEC : 0))
  147. #endif /* LINUXELF_H */