Branch data Line data Source code
1 : : /* Rewritten by Rusty Russell, on the backs of many others...
2 : : Copyright (C) 2001 Rusty Russell, 2002 Rusty Russell IBM.
3 : :
4 : : This program is free software; you can redistribute it and/or modify
5 : : it under the terms of the GNU General Public License as published by
6 : : the Free Software Foundation; either version 2 of the License, or
7 : : (at your option) any later version.
8 : :
9 : : This program is distributed in the hope that it will be useful,
10 : : but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : : GNU General Public License for more details.
13 : :
14 : : You should have received a copy of the GNU General Public License
15 : : along with this program; if not, write to the Free Software
16 : : Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 : : */
18 : : #include <linux/ftrace.h>
19 : : #include <linux/memory.h>
20 : : #include <linux/module.h>
21 : : #include <linux/mutex.h>
22 : : #include <linux/init.h>
23 : :
24 : : #include <asm/sections.h>
25 : : #include <asm/uaccess.h>
26 : :
27 : : /*
28 : : * mutex protecting text section modification (dynamic code patching).
29 : : * some users need to sleep (allocating memory...) while they hold this lock.
30 : : *
31 : : * NOT exported to modules - patching kernel text is a really delicate matter.
32 : : */
33 : : DEFINE_MUTEX(text_mutex);
34 : :
35 : : extern struct exception_table_entry __start___ex_table[];
36 : : extern struct exception_table_entry __stop___ex_table[];
37 : :
38 : : /* Cleared by build time tools if the table is already sorted. */
39 : : u32 __initdata main_extable_sort_needed = 1;
40 : :
41 : : /* Sort the kernel's built-in exception table */
42 : 0 : void __init sort_main_extable(void)
43 : : {
44 [ # # ][ # # ]: 0 : if (main_extable_sort_needed && __stop___ex_table > __start___ex_table) {
45 : 0 : pr_notice("Sorting __ex_table...\n");
46 : 0 : sort_extable(__start___ex_table, __stop___ex_table);
47 : : }
48 : 0 : }
49 : :
50 : : /* Given an address, look for it in the exception tables. */
51 : 0 : const struct exception_table_entry *search_exception_tables(unsigned long addr)
52 : : {
53 : : const struct exception_table_entry *e;
54 : :
55 : 24466 : e = search_extable(__start___ex_table, __stop___ex_table-1, addr);
56 [ - + ]: 24449 : if (!e)
57 : 0 : e = search_module_extables(addr);
58 : 0 : return e;
59 : : }
60 : :
61 : : static inline int init_kernel_text(unsigned long addr)
62 : : {
63 [ # # ][ # # ]: 0 : if (addr >= (unsigned long)_sinittext &&
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
64 : 0 : addr < (unsigned long)_einittext)
65 : : return 1;
66 : : return 0;
67 : : }
68 : :
69 : 0 : int core_kernel_text(unsigned long addr)
70 : : {
71 [ # # ][ # # ]: 46944 : if (addr >= (unsigned long)_stext &&
[ + - ][ - + ]
[ # # ][ # # ]
[ + - ][ + - ]
72 : 46944 : addr < (unsigned long)_etext)
73 : : return 1;
74 : :
75 [ # # ][ # # ]: 23472 : if (system_state == SYSTEM_BOOTING &&
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
76 : : init_kernel_text(addr))
77 : : return 1;
78 : 0 : return 0;
79 : : }
80 : :
81 : : /**
82 : : * core_kernel_data - tell if addr points to kernel data
83 : : * @addr: address to test
84 : : *
85 : : * Returns true if @addr passed in is from the core kernel data
86 : : * section.
87 : : *
88 : : * Note: On some archs it may return true for core RODATA, and false
89 : : * for others. But will always be true for core RW data.
90 : : */
91 : 0 : int core_kernel_data(unsigned long addr)
92 : : {
93 [ # # ][ # # ]: 0 : if (addr >= (unsigned long)_sdata &&
94 : 0 : addr < (unsigned long)_edata)
95 : : return 1;
96 : 0 : return 0;
97 : : }
98 : :
99 : 0 : int __kernel_text_address(unsigned long addr)
100 : : {
101 [ # # ]: 0 : if (core_kernel_text(addr))
102 : : return 1;
103 [ # # ]: 0 : if (is_module_text_address(addr))
104 : : return 1;
105 : : /*
106 : : * There might be init symbols in saved stacktraces.
107 : : * Give those symbols a chance to be printed in
108 : : * backtraces (such as lockdep traces).
109 : : *
110 : : * Since we are after the module-symbols check, there's
111 : : * no danger of address overlap:
112 : : */
113 [ # # ]: 0 : if (init_kernel_text(addr))
114 : : return 1;
115 : 0 : return 0;
116 : : }
117 : :
118 : 0 : int kernel_text_address(unsigned long addr)
119 : : {
120 [ # # ]: 23472 : if (core_kernel_text(addr))
121 : : return 1;
122 : 0 : return is_module_text_address(addr);
123 : : }
124 : :
125 : : /*
126 : : * On some architectures (PPC64, IA64) function pointers
127 : : * are actually only tokens to some data that then holds the
128 : : * real function address. As a result, to find if a function
129 : : * pointer is part of the kernel text, we need to do some
130 : : * special dereferencing first.
131 : : */
132 : 0 : int func_ptr_is_kernel_text(void *ptr)
133 : : {
134 : : unsigned long addr;
135 : 0 : addr = (unsigned long) dereference_function_descriptor(ptr);
136 [ # # ]: 0 : if (core_kernel_text(addr))
137 : : return 1;
138 : 0 : return is_module_text_address(addr);
139 : : }
|