Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /* Rewritten and vastly simplified by Rusty Russell for in-kernel
0003  * module loader:
0004  *   Copyright 2002 Rusty Russell <rusty@rustcorp.com.au> IBM Corporation
0005  */
0006 #ifndef _LINUX_KALLSYMS_H
0007 #define _LINUX_KALLSYMS_H
0008 
0009 #include <linux/errno.h>
0010 #include <linux/buildid.h>
0011 #include <linux/kernel.h>
0012 #include <linux/stddef.h>
0013 #include <linux/mm.h>
0014 #include <linux/module.h>
0015 
0016 #include <asm/sections.h>
0017 
0018 #define KSYM_NAME_LEN 128
0019 #define KSYM_SYMBOL_LEN (sizeof("%s+%#lx/%#lx [%s %s]") + \
0020             (KSYM_NAME_LEN - 1) + \
0021             2*(BITS_PER_LONG*3/10) + (MODULE_NAME_LEN - 1) + \
0022             (BUILD_ID_SIZE_MAX * 2) + 1)
0023 
0024 struct cred;
0025 struct module;
0026 
0027 static inline int is_kernel_text(unsigned long addr)
0028 {
0029     if (__is_kernel_text(addr))
0030         return 1;
0031     return in_gate_area_no_mm(addr);
0032 }
0033 
0034 static inline int is_kernel(unsigned long addr)
0035 {
0036     if (__is_kernel(addr))
0037         return 1;
0038     return in_gate_area_no_mm(addr);
0039 }
0040 
0041 static inline int is_ksym_addr(unsigned long addr)
0042 {
0043     if (IS_ENABLED(CONFIG_KALLSYMS_ALL))
0044         return is_kernel(addr);
0045 
0046     return is_kernel_text(addr) || is_kernel_inittext(addr);
0047 }
0048 
0049 static inline void *dereference_symbol_descriptor(void *ptr)
0050 {
0051 #ifdef CONFIG_HAVE_FUNCTION_DESCRIPTORS
0052     struct module *mod;
0053 
0054     ptr = dereference_kernel_function_descriptor(ptr);
0055     if (is_ksym_addr((unsigned long)ptr))
0056         return ptr;
0057 
0058     preempt_disable();
0059     mod = __module_address((unsigned long)ptr);
0060     preempt_enable();
0061 
0062     if (mod)
0063         ptr = dereference_module_function_descriptor(mod, ptr);
0064 #endif
0065     return ptr;
0066 }
0067 
0068 #ifdef CONFIG_KALLSYMS
0069 int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *,
0070                       unsigned long),
0071                 void *data);
0072 
0073 /* Lookup the address for a symbol. Returns 0 if not found. */
0074 unsigned long kallsyms_lookup_name(const char *name);
0075 
0076 extern int kallsyms_lookup_size_offset(unsigned long addr,
0077                   unsigned long *symbolsize,
0078                   unsigned long *offset);
0079 
0080 /* Lookup an address.  modname is set to NULL if it's in the kernel. */
0081 const char *kallsyms_lookup(unsigned long addr,
0082                 unsigned long *symbolsize,
0083                 unsigned long *offset,
0084                 char **modname, char *namebuf);
0085 
0086 /* Look up a kernel symbol and return it in a text buffer. */
0087 extern int sprint_symbol(char *buffer, unsigned long address);
0088 extern int sprint_symbol_build_id(char *buffer, unsigned long address);
0089 extern int sprint_symbol_no_offset(char *buffer, unsigned long address);
0090 extern int sprint_backtrace(char *buffer, unsigned long address);
0091 extern int sprint_backtrace_build_id(char *buffer, unsigned long address);
0092 
0093 int lookup_symbol_name(unsigned long addr, char *symname);
0094 int lookup_symbol_attrs(unsigned long addr, unsigned long *size, unsigned long *offset, char *modname, char *name);
0095 
0096 /* How and when do we show kallsyms values? */
0097 extern bool kallsyms_show_value(const struct cred *cred);
0098 
0099 #else /* !CONFIG_KALLSYMS */
0100 
0101 static inline unsigned long kallsyms_lookup_name(const char *name)
0102 {
0103     return 0;
0104 }
0105 
0106 static inline int kallsyms_lookup_size_offset(unsigned long addr,
0107                           unsigned long *symbolsize,
0108                           unsigned long *offset)
0109 {
0110     return 0;
0111 }
0112 
0113 static inline const char *kallsyms_lookup(unsigned long addr,
0114                       unsigned long *symbolsize,
0115                       unsigned long *offset,
0116                       char **modname, char *namebuf)
0117 {
0118     return NULL;
0119 }
0120 
0121 static inline int sprint_symbol(char *buffer, unsigned long addr)
0122 {
0123     *buffer = '\0';
0124     return 0;
0125 }
0126 
0127 static inline int sprint_symbol_build_id(char *buffer, unsigned long address)
0128 {
0129     *buffer = '\0';
0130     return 0;
0131 }
0132 
0133 static inline int sprint_symbol_no_offset(char *buffer, unsigned long addr)
0134 {
0135     *buffer = '\0';
0136     return 0;
0137 }
0138 
0139 static inline int sprint_backtrace(char *buffer, unsigned long addr)
0140 {
0141     *buffer = '\0';
0142     return 0;
0143 }
0144 
0145 static inline int sprint_backtrace_build_id(char *buffer, unsigned long addr)
0146 {
0147     *buffer = '\0';
0148     return 0;
0149 }
0150 
0151 static inline int lookup_symbol_name(unsigned long addr, char *symname)
0152 {
0153     return -ERANGE;
0154 }
0155 
0156 static inline int lookup_symbol_attrs(unsigned long addr, unsigned long *size, unsigned long *offset, char *modname, char *name)
0157 {
0158     return -ERANGE;
0159 }
0160 
0161 static inline bool kallsyms_show_value(const struct cred *cred)
0162 {
0163     return false;
0164 }
0165 
0166 static inline int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *,
0167                       unsigned long), void *data)
0168 {
0169     return -EOPNOTSUPP;
0170 }
0171 #endif /*CONFIG_KALLSYMS*/
0172 
0173 static inline void print_ip_sym(const char *loglvl, unsigned long ip)
0174 {
0175     printk("%s[<%px>] %pS\n", loglvl, (void *) ip, (void *) ip);
0176 }
0177 
0178 #endif /*_LINUX_KALLSYMS_H*/