kallsyms.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /* Rewritten and vastly simplified by Rusty Russell for in-kernel
  3. * module loader:
  4. * Copyright 2002 Rusty Russell <rusty@rustcorp.com.au> IBM Corporation
  5. */
  6. #ifndef _LINUX_KALLSYMS_H
  7. #define _LINUX_KALLSYMS_H
  8. #include <linux/errno.h>
  9. #include <linux/kernel.h>
  10. #include <linux/stddef.h>
  11. #include <linux/mm.h>
  12. #include <linux/module.h>
  13. #include <asm/sections.h>
  14. #define KSYM_NAME_LEN 128
  15. #define KSYM_SYMBOL_LEN (sizeof("%s+%#lx/%#lx [%s]") + (KSYM_NAME_LEN - 1) + \
  16. 2*(BITS_PER_LONG*3/10) + (MODULE_NAME_LEN - 1) + 1)
  17. #ifndef CONFIG_64BIT
  18. # define KALLSYM_FMT "%08lx"
  19. #else
  20. # define KALLSYM_FMT "%016lx"
  21. #endif
  22. struct module;
  23. static inline int is_kernel_inittext(unsigned long addr)
  24. {
  25. if (addr >= (unsigned long)_sinittext
  26. && addr <= (unsigned long)_einittext)
  27. return 1;
  28. return 0;
  29. }
  30. static inline int is_kernel_text(unsigned long addr)
  31. {
  32. if ((addr >= (unsigned long)_stext && addr <= (unsigned long)_etext) ||
  33. arch_is_kernel_text(addr))
  34. return 1;
  35. return in_gate_area_no_mm(addr);
  36. }
  37. static inline int is_kernel(unsigned long addr)
  38. {
  39. if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end)
  40. return 1;
  41. return in_gate_area_no_mm(addr);
  42. }
  43. static inline int is_ksym_addr(unsigned long addr)
  44. {
  45. if (IS_ENABLED(CONFIG_KALLSYMS_ALL))
  46. return is_kernel(addr);
  47. return is_kernel_text(addr) || is_kernel_inittext(addr);
  48. }
  49. static inline void *dereference_symbol_descriptor(void *ptr)
  50. {
  51. #ifdef HAVE_DEREFERENCE_FUNCTION_DESCRIPTOR
  52. struct module *mod;
  53. ptr = dereference_kernel_function_descriptor(ptr);
  54. if (is_ksym_addr((unsigned long)ptr))
  55. return ptr;
  56. preempt_disable();
  57. mod = __module_address((unsigned long)ptr);
  58. preempt_enable();
  59. if (mod)
  60. ptr = dereference_module_function_descriptor(mod, ptr);
  61. #endif
  62. return ptr;
  63. }
  64. #ifdef CONFIG_KALLSYMS
  65. /* Lookup the address for a symbol. Returns 0 if not found. */
  66. unsigned long kallsyms_lookup_name(const char *name);
  67. /* Call a function on each kallsyms symbol in the core kernel */
  68. int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *,
  69. unsigned long),
  70. void *data);
  71. extern int kallsyms_lookup_size_offset(unsigned long addr,
  72. unsigned long *symbolsize,
  73. unsigned long *offset);
  74. /* Lookup an address. modname is set to NULL if it's in the kernel. */
  75. const char *kallsyms_lookup(unsigned long addr,
  76. unsigned long *symbolsize,
  77. unsigned long *offset,
  78. char **modname, char *namebuf);
  79. /* Look up a kernel symbol and return it in a text buffer. */
  80. extern int sprint_symbol(char *buffer, unsigned long address);
  81. extern int sprint_symbol_no_offset(char *buffer, unsigned long address);
  82. extern int sprint_backtrace(char *buffer, unsigned long address);
  83. /* Look up a kernel symbol and print it to the kernel messages. */
  84. extern void __print_symbol(const char *fmt, unsigned long address);
  85. int lookup_symbol_name(unsigned long addr, char *symname);
  86. int lookup_symbol_attrs(unsigned long addr, unsigned long *size, unsigned long *offset, char *modname, char *name);
  87. /* How and when do we show kallsyms values? */
  88. extern int kallsyms_show_value(void);
  89. #else /* !CONFIG_KALLSYMS */
  90. static inline unsigned long kallsyms_lookup_name(const char *name)
  91. {
  92. return 0;
  93. }
  94. static inline int kallsyms_on_each_symbol(int (*fn)(void *, const char *,
  95. struct module *,
  96. unsigned long),
  97. void *data)
  98. {
  99. return 0;
  100. }
  101. static inline int kallsyms_lookup_size_offset(unsigned long addr,
  102. unsigned long *symbolsize,
  103. unsigned long *offset)
  104. {
  105. return 0;
  106. }
  107. static inline const char *kallsyms_lookup(unsigned long addr,
  108. unsigned long *symbolsize,
  109. unsigned long *offset,
  110. char **modname, char *namebuf)
  111. {
  112. return NULL;
  113. }
  114. static inline int sprint_symbol(char *buffer, unsigned long addr)
  115. {
  116. *buffer = '\0';
  117. return 0;
  118. }
  119. static inline int sprint_symbol_no_offset(char *buffer, unsigned long addr)
  120. {
  121. *buffer = '\0';
  122. return 0;
  123. }
  124. static inline int sprint_backtrace(char *buffer, unsigned long addr)
  125. {
  126. *buffer = '\0';
  127. return 0;
  128. }
  129. static inline int lookup_symbol_name(unsigned long addr, char *symname)
  130. {
  131. return -ERANGE;
  132. }
  133. static inline int lookup_symbol_attrs(unsigned long addr, unsigned long *size, unsigned long *offset, char *modname, char *name)
  134. {
  135. return -ERANGE;
  136. }
  137. static inline int kallsyms_show_value(void)
  138. {
  139. return false;
  140. }
  141. /* Stupid that this does nothing, but I didn't create this mess. */
  142. #define __print_symbol(fmt, addr)
  143. #endif /*CONFIG_KALLSYMS*/
  144. /* This macro allows us to keep printk typechecking */
  145. static __printf(1, 2)
  146. void __check_printsym_format(const char *fmt, ...)
  147. {
  148. }
  149. static inline void print_symbol(const char *fmt, unsigned long addr)
  150. {
  151. __check_printsym_format(fmt, "");
  152. __print_symbol(fmt, (unsigned long)
  153. __builtin_extract_return_addr((void *)addr));
  154. }
  155. static inline void print_ip_sym(unsigned long ip)
  156. {
  157. printk("[<%p>] %pS\n", (void *) ip, (void *) ip);
  158. }
  159. #endif /*_LINUX_KALLSYMS_H*/