dl.h 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. /* dl.h - types and prototypes for loadable module support */
  2. /*
  3. * GRUB -- GRand Unified Bootloader
  4. * Copyright (C) 2002,2004,2005,2007,2008,2009 Free Software Foundation, Inc.
  5. *
  6. * GRUB is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * GRUB is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #ifndef GRUB_DL_H
  20. #define GRUB_DL_H 1
  21. #include <grub/symbol.h>
  22. #ifndef ASM_FILE
  23. #include <grub/err.h>
  24. #include <grub/types.h>
  25. #include <grub/elf.h>
  26. #include <grub/list.h>
  27. #include <grub/misc.h>
  28. #endif
  29. /*
  30. * Macros GRUB_MOD_INIT and GRUB_MOD_FINI are also used by build rules
  31. * to collect module names, so we define them only when they are not
  32. * defined already.
  33. */
  34. #ifndef ASM_FILE
  35. #ifndef GRUB_MOD_INIT
  36. #if !defined (GRUB_UTIL) && !defined (GRUB_MACHINE_EMU) && !defined (GRUB_KERNEL)
  37. #define GRUB_MOD_INIT(name) \
  38. static void grub_mod_init (grub_dl_t mod __attribute__ ((unused))) __attribute__ ((used)); \
  39. static void \
  40. grub_mod_init (grub_dl_t mod __attribute__ ((unused)))
  41. #define GRUB_MOD_FINI(name) \
  42. static void grub_mod_fini (void) __attribute__ ((used)); \
  43. static void \
  44. grub_mod_fini (void)
  45. #elif defined (GRUB_KERNEL)
  46. #define GRUB_MOD_INIT(name) \
  47. static void grub_mod_init (grub_dl_t mod __attribute__ ((unused))) __attribute__ ((used)); \
  48. void \
  49. grub_##name##_init (void) { grub_mod_init (0); } \
  50. static void \
  51. grub_mod_init (grub_dl_t mod __attribute__ ((unused)))
  52. #define GRUB_MOD_FINI(name) \
  53. static void grub_mod_fini (void) __attribute__ ((used)); \
  54. void \
  55. grub_##name##_fini (void) { grub_mod_fini (); } \
  56. static void \
  57. grub_mod_fini (void)
  58. #else
  59. #define GRUB_MOD_INIT(name) \
  60. static void grub_mod_init (grub_dl_t mod __attribute__ ((unused))) __attribute__ ((used)); \
  61. void grub_##name##_init (void); \
  62. void \
  63. grub_##name##_init (void) { grub_mod_init (0); } \
  64. static void \
  65. grub_mod_init (grub_dl_t mod __attribute__ ((unused)))
  66. #define GRUB_MOD_FINI(name) \
  67. static void grub_mod_fini (void) __attribute__ ((used)); \
  68. void grub_##name##_fini (void); \
  69. void \
  70. grub_##name##_fini (void) { grub_mod_fini (); } \
  71. static void \
  72. grub_mod_fini (void)
  73. #endif
  74. #endif
  75. #endif
  76. #ifndef ASM_FILE
  77. #ifdef __APPLE__
  78. #define GRUB_MOD_SECTION(x) "_" #x ", _" #x ""
  79. #else
  80. #define GRUB_MOD_SECTION(x) "." #x
  81. #endif
  82. #else
  83. #ifdef __APPLE__
  84. #define GRUB_MOD_SECTION(x) _ ## x , _ ##x
  85. #else
  86. #define GRUB_MOD_SECTION(x) . ## x
  87. #endif
  88. #endif
  89. /* Me, Vladimir Serbinenko, hereby I add this module check as per new
  90. GNU module policy. Note that this license check is informative only.
  91. Modules have to be licensed under GPLv3 or GPLv3+ (optionally
  92. multi-licensed under other licences as well) independently of the
  93. presence of this check and solely by linking (module loading in GRUB
  94. constitutes linking) and GRUB core being licensed under GPLv3+.
  95. Be sure to understand your license obligations.
  96. */
  97. #ifndef ASM_FILE
  98. #if GNUC_PREREQ (3,2)
  99. #define ATTRIBUTE_USED __used__
  100. #else
  101. #define ATTRIBUTE_USED __unused__
  102. #endif
  103. #define GRUB_MOD_LICENSE(license) \
  104. static const char grub_module_license[] __attribute__ ((section (GRUB_MOD_SECTION (module_license)), ATTRIBUTE_USED)) = "LICENSE=" license;
  105. #define GRUB_MOD_DEP(name) \
  106. static const char grub_module_depend_##name[] \
  107. __attribute__((section(GRUB_MOD_SECTION(moddeps)), ATTRIBUTE_USED)) = #name
  108. #define GRUB_MOD_NAME(name) \
  109. static const char grub_module_name_##name[] \
  110. __attribute__((section(GRUB_MOD_SECTION(modname)), __used__)) = #name
  111. #else
  112. #ifdef __APPLE__
  113. .macro GRUB_MOD_LICENSE
  114. .section GRUB_MOD_SECTION(module_license)
  115. .ascii "LICENSE="
  116. .ascii $0
  117. .byte 0
  118. .endm
  119. #else
  120. .macro GRUB_MOD_LICENSE license
  121. .section GRUB_MOD_SECTION(module_license), "a"
  122. .ascii "LICENSE="
  123. .ascii "\license"
  124. .byte 0
  125. .endm
  126. #endif
  127. #endif
  128. /* Under GPL license obligations you have to distribute your module
  129. under GPLv3(+). However, you can also distribute the same code under
  130. another license as long as GPLv3(+) version is provided.
  131. */
  132. #define GRUB_MOD_DUAL_LICENSE(x)
  133. #ifndef ASM_FILE
  134. struct grub_dl_segment
  135. {
  136. struct grub_dl_segment *next;
  137. void *addr;
  138. grub_size_t size;
  139. unsigned section;
  140. };
  141. typedef struct grub_dl_segment *grub_dl_segment_t;
  142. struct grub_dl;
  143. struct grub_dl_dep
  144. {
  145. struct grub_dl_dep *next;
  146. struct grub_dl *mod;
  147. };
  148. typedef struct grub_dl_dep *grub_dl_dep_t;
  149. #ifndef GRUB_UTIL
  150. struct grub_dl
  151. {
  152. char *name;
  153. grub_uint64_t ref_count;
  154. int persistent;
  155. grub_dl_dep_t dep;
  156. grub_dl_segment_t segment;
  157. Elf_Sym *symtab;
  158. grub_size_t symsize;
  159. void (*init) (struct grub_dl *mod);
  160. void (*fini) (void);
  161. #if !defined (__i386__) && !defined (__x86_64__)
  162. void *got;
  163. void *gotptr;
  164. void *tramp;
  165. void *trampptr;
  166. #endif
  167. #ifdef __mips__
  168. grub_uint32_t *reginfo;
  169. #endif
  170. void *base;
  171. grub_size_t sz;
  172. struct grub_dl *next;
  173. };
  174. #endif
  175. typedef struct grub_dl *grub_dl_t;
  176. grub_dl_t grub_dl_load_file (const char *filename);
  177. grub_dl_t EXPORT_FUNC(grub_dl_load) (const char *name);
  178. grub_dl_t grub_dl_load_core (void *addr, grub_size_t size);
  179. grub_dl_t EXPORT_FUNC(grub_dl_load_core_noinit) (void *addr, grub_size_t size);
  180. int EXPORT_FUNC(grub_dl_unload) (grub_dl_t mod);
  181. extern grub_uint64_t EXPORT_FUNC(grub_dl_ref) (grub_dl_t mod);
  182. extern grub_uint64_t EXPORT_FUNC(grub_dl_unref) (grub_dl_t mod);
  183. extern grub_uint64_t EXPORT_FUNC(grub_dl_ref_count) (grub_dl_t mod);
  184. extern grub_dl_t EXPORT_VAR(grub_dl_head);
  185. #ifndef GRUB_UTIL
  186. #define FOR_DL_MODULES(var) FOR_LIST_ELEMENTS ((var), (grub_dl_head))
  187. #ifdef GRUB_MACHINE_EMU
  188. void *
  189. grub_osdep_dl_memalign (grub_size_t align, grub_size_t size);
  190. void
  191. grub_dl_osdep_dl_free (void *ptr);
  192. #endif
  193. static inline void
  194. grub_dl_init (grub_dl_t mod)
  195. {
  196. if (mod->init)
  197. (mod->init) (mod);
  198. mod->next = grub_dl_head;
  199. grub_dl_head = mod;
  200. }
  201. static inline grub_dl_t
  202. grub_dl_get (const char *name)
  203. {
  204. grub_dl_t l;
  205. FOR_DL_MODULES(l)
  206. if (grub_strcmp (name, l->name) == 0)
  207. return l;
  208. return 0;
  209. }
  210. static inline void
  211. grub_dl_set_persistent (grub_dl_t mod)
  212. {
  213. mod->persistent = 1;
  214. }
  215. static inline int
  216. grub_dl_is_persistent (grub_dl_t mod)
  217. {
  218. return mod->persistent;
  219. }
  220. #endif
  221. grub_err_t grub_dl_register_symbol (const char *name, void *addr,
  222. int isfunc, grub_dl_t mod);
  223. grub_err_t grub_arch_dl_check_header (void *ehdr);
  224. #ifndef GRUB_UTIL
  225. grub_err_t
  226. grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
  227. Elf_Shdr *s, grub_dl_segment_t seg);
  228. #endif
  229. #if defined (_mips)
  230. #define GRUB_LINKER_HAVE_INIT 1
  231. void grub_arch_dl_init_linker (void);
  232. #endif
  233. #define GRUB_IA64_DL_TRAMP_ALIGN 16
  234. #define GRUB_IA64_DL_GOT_ALIGN 16
  235. grub_err_t
  236. grub_ia64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
  237. grub_size_t *got);
  238. grub_err_t
  239. grub_arm64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
  240. grub_size_t *got);
  241. #if defined (__ia64__)
  242. #define GRUB_ARCH_DL_TRAMP_ALIGN GRUB_IA64_DL_TRAMP_ALIGN
  243. #define GRUB_ARCH_DL_GOT_ALIGN GRUB_IA64_DL_GOT_ALIGN
  244. #define grub_arch_dl_get_tramp_got_size grub_ia64_dl_get_tramp_got_size
  245. #elif defined (__aarch64__)
  246. #define grub_arch_dl_get_tramp_got_size grub_arm64_dl_get_tramp_got_size
  247. #else
  248. grub_err_t
  249. grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
  250. grub_size_t *got);
  251. #endif
  252. #if defined (__powerpc__) || defined (__mips__) || defined (__arm__) || \
  253. (defined(__riscv) && (__riscv_xlen == 32))
  254. #define GRUB_ARCH_DL_TRAMP_ALIGN 4
  255. #define GRUB_ARCH_DL_GOT_ALIGN 4
  256. #endif
  257. #if defined (__aarch64__) || defined (__sparc__) || \
  258. defined (__loongarch_lp64) || \
  259. (defined(__riscv) && (__riscv_xlen == 64))
  260. #define GRUB_ARCH_DL_TRAMP_ALIGN 8
  261. #define GRUB_ARCH_DL_GOT_ALIGN 8
  262. #endif
  263. #endif
  264. #endif /* ! GRUB_DL_H */