Back to home page

LXR

 
 

    


0001 /* Rewritten by Rusty Russell, on the backs of many others...
0002    Copyright (C) 2001 Rusty Russell, 2002 Rusty Russell IBM.
0003 
0004     This program is free software; you can redistribute it and/or modify
0005     it under the terms of the GNU General Public License as published by
0006     the Free Software Foundation; either version 2 of the License, or
0007     (at your option) any later version.
0008 
0009     This program is distributed in the hope that it will be useful,
0010     but WITHOUT ANY WARRANTY; without even the implied warranty of
0011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0012     GNU General Public License for more details.
0013 
0014     You should have received a copy of the GNU General Public License
0015     along with this program; if not, write to the Free Software
0016     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
0017 */
0018 #include <linux/ftrace.h>
0019 #include <linux/memory.h>
0020 #include <linux/module.h>
0021 #include <linux/mutex.h>
0022 #include <linux/init.h>
0023 
0024 #include <asm/sections.h>
0025 #include <linux/uaccess.h>
0026 
0027 /*
0028  * mutex protecting text section modification (dynamic code patching).
0029  * some users need to sleep (allocating memory...) while they hold this lock.
0030  *
0031  * NOT exported to modules - patching kernel text is a really delicate matter.
0032  */
0033 DEFINE_MUTEX(text_mutex);
0034 
0035 extern struct exception_table_entry __start___ex_table[];
0036 extern struct exception_table_entry __stop___ex_table[];
0037 
0038 /* Cleared by build time tools if the table is already sorted. */
0039 u32 __initdata __visible main_extable_sort_needed = 1;
0040 
0041 /* Sort the kernel's built-in exception table */
0042 void __init sort_main_extable(void)
0043 {
0044     if (main_extable_sort_needed && __stop___ex_table > __start___ex_table) {
0045         pr_notice("Sorting __ex_table...\n");
0046         sort_extable(__start___ex_table, __stop___ex_table);
0047     }
0048 }
0049 
0050 /* Given an address, look for it in the exception tables. */
0051 const struct exception_table_entry *search_exception_tables(unsigned long addr)
0052 {
0053     const struct exception_table_entry *e;
0054 
0055     e = search_extable(__start___ex_table, __stop___ex_table-1, addr);
0056     if (!e)
0057         e = search_module_extables(addr);
0058     return e;
0059 }
0060 
0061 static inline int init_kernel_text(unsigned long addr)
0062 {
0063     if (addr >= (unsigned long)_sinittext &&
0064         addr < (unsigned long)_einittext)
0065         return 1;
0066     return 0;
0067 }
0068 
0069 int core_kernel_text(unsigned long addr)
0070 {
0071     if (addr >= (unsigned long)_stext &&
0072         addr < (unsigned long)_etext)
0073         return 1;
0074 
0075     if (system_state == SYSTEM_BOOTING &&
0076         init_kernel_text(addr))
0077         return 1;
0078     return 0;
0079 }
0080 
0081 /**
0082  * core_kernel_data - tell if addr points to kernel data
0083  * @addr: address to test
0084  *
0085  * Returns true if @addr passed in is from the core kernel data
0086  * section.
0087  *
0088  * Note: On some archs it may return true for core RODATA, and false
0089  *  for others. But will always be true for core RW data.
0090  */
0091 int core_kernel_data(unsigned long addr)
0092 {
0093     if (addr >= (unsigned long)_sdata &&
0094         addr < (unsigned long)_edata)
0095         return 1;
0096     return 0;
0097 }
0098 
0099 int __kernel_text_address(unsigned long addr)
0100 {
0101     if (core_kernel_text(addr))
0102         return 1;
0103     if (is_module_text_address(addr))
0104         return 1;
0105     if (is_ftrace_trampoline(addr))
0106         return 1;
0107     /*
0108      * There might be init symbols in saved stacktraces.
0109      * Give those symbols a chance to be printed in
0110      * backtraces (such as lockdep traces).
0111      *
0112      * Since we are after the module-symbols check, there's
0113      * no danger of address overlap:
0114      */
0115     if (init_kernel_text(addr))
0116         return 1;
0117     return 0;
0118 }
0119 
0120 int kernel_text_address(unsigned long addr)
0121 {
0122     if (core_kernel_text(addr))
0123         return 1;
0124     if (is_module_text_address(addr))
0125         return 1;
0126     return is_ftrace_trampoline(addr);
0127 }
0128 
0129 /*
0130  * On some architectures (PPC64, IA64) function pointers
0131  * are actually only tokens to some data that then holds the
0132  * real function address. As a result, to find if a function
0133  * pointer is part of the kernel text, we need to do some
0134  * special dereferencing first.
0135  */
0136 int func_ptr_is_kernel_text(void *ptr)
0137 {
0138     unsigned long addr;
0139     addr = (unsigned long) dereference_function_descriptor(ptr);
0140     if (core_kernel_text(addr))
0141         return 1;
0142     return is_module_text_address(addr);
0143 }