diff options
-rw-r--r-- | include/asm-generic/vmlinux.lds.h | 88 | ||||
-rw-r--r-- | include/linux/init.h | 77 | ||||
-rw-r--r-- | scripts/mod/modpost.c | 54 |
3 files changed, 159 insertions, 60 deletions
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index ae0166e83490..e0a56fb8f813 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h | |||
@@ -9,10 +9,46 @@ | |||
9 | /* Align . to a 8 byte boundary equals to maximum function alignment. */ | 9 | /* Align . to a 8 byte boundary equals to maximum function alignment. */ |
10 | #define ALIGN_FUNCTION() . = ALIGN(8) | 10 | #define ALIGN_FUNCTION() . = ALIGN(8) |
11 | 11 | ||
12 | /* The actual configuration determine if the init/exit sections | ||
13 | * are handled as text/data or they can be discarded (which | ||
14 | * often happens at runtime) | ||
15 | */ | ||
16 | #ifdef CONFIG_HOTPLUG | ||
17 | #define DEV_KEEP(sec) *(.dev##sec) | ||
18 | #define DEV_DISCARD(sec) | ||
19 | #else | ||
20 | #define DEV_KEEP(sec) | ||
21 | #define DEV_DISCARD(sec) *(.dev##sec) | ||
22 | #endif | ||
23 | |||
24 | #ifdef CONFIG_HOTPLUG_CPU | ||
25 | #define CPU_KEEP(sec) *(.cpu##sec) | ||
26 | #define CPU_DISCARD(sec) | ||
27 | #else | ||
28 | #define CPU_KEEP(sec) | ||
29 | #define CPU_DISCARD(sec) *(.cpu##sec) | ||
30 | #endif | ||
31 | |||
32 | #if defined(CONFIG_MEMORY_HOTPLUG) || defined(CONFIG_ACPI_HOTPLUG_MEMORY) \ | ||
33 | || defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE) | ||
34 | #define MEM_KEEP(sec) *(.mem##sec) | ||
35 | #define MEM_DISCARD(sec) | ||
36 | #else | ||
37 | #define MEM_KEEP(sec) | ||
38 | #define MEM_DISCARD(sec) *(.mem##sec) | ||
39 | #endif | ||
40 | |||
41 | |||
12 | /* .data section */ | 42 | /* .data section */ |
13 | #define DATA_DATA \ | 43 | #define DATA_DATA \ |
14 | *(.data) \ | 44 | *(.data) \ |
15 | *(.data.init.refok) \ | 45 | *(.data.init.refok) \ |
46 | DEV_KEEP(init.data) \ | ||
47 | DEV_KEEP(exit.data) \ | ||
48 | CPU_KEEP(init.data) \ | ||
49 | CPU_KEEP(exit.data) \ | ||
50 | MEM_KEEP(init.data) \ | ||
51 | MEM_KEEP(exit.data) \ | ||
16 | . = ALIGN(8); \ | 52 | . = ALIGN(8); \ |
17 | VMLINUX_SYMBOL(__start___markers) = .; \ | 53 | VMLINUX_SYMBOL(__start___markers) = .; \ |
18 | *(__markers) \ | 54 | *(__markers) \ |
@@ -132,6 +168,16 @@ | |||
132 | *(__ksymtab_strings) \ | 168 | *(__ksymtab_strings) \ |
133 | } \ | 169 | } \ |
134 | \ | 170 | \ |
171 | /* __*init sections */ \ | ||
172 | __init_rodata : AT(ADDR(__init_rodata) - LOAD_OFFSET) { \ | ||
173 | DEV_KEEP(init.rodata) \ | ||
174 | DEV_KEEP(exit.rodata) \ | ||
175 | CPU_KEEP(init.rodata) \ | ||
176 | CPU_KEEP(exit.rodata) \ | ||
177 | MEM_KEEP(init.rodata) \ | ||
178 | MEM_KEEP(exit.rodata) \ | ||
179 | } \ | ||
180 | \ | ||
135 | /* Built-in module parameters. */ \ | 181 | /* Built-in module parameters. */ \ |
136 | __param : AT(ADDR(__param) - LOAD_OFFSET) { \ | 182 | __param : AT(ADDR(__param) - LOAD_OFFSET) { \ |
137 | VMLINUX_SYMBOL(__start___param) = .; \ | 183 | VMLINUX_SYMBOL(__start___param) = .; \ |
@@ -139,7 +185,6 @@ | |||
139 | VMLINUX_SYMBOL(__stop___param) = .; \ | 185 | VMLINUX_SYMBOL(__stop___param) = .; \ |
140 | VMLINUX_SYMBOL(__end_rodata) = .; \ | 186 | VMLINUX_SYMBOL(__end_rodata) = .; \ |
141 | } \ | 187 | } \ |
142 | \ | ||
143 | . = ALIGN((align)); | 188 | . = ALIGN((align)); |
144 | 189 | ||
145 | /* RODATA provided for backward compatibility. | 190 | /* RODATA provided for backward compatibility. |
@@ -159,7 +204,14 @@ | |||
159 | ALIGN_FUNCTION(); \ | 204 | ALIGN_FUNCTION(); \ |
160 | *(.text) \ | 205 | *(.text) \ |
161 | *(.text.init.refok) \ | 206 | *(.text.init.refok) \ |
162 | *(.exit.text.refok) | 207 | *(.exit.text.refok) \ |
208 | DEV_KEEP(init.text) \ | ||
209 | DEV_KEEP(exit.text) \ | ||
210 | CPU_KEEP(init.text) \ | ||
211 | CPU_KEEP(exit.text) \ | ||
212 | MEM_KEEP(init.text) \ | ||
213 | MEM_KEEP(exit.text) | ||
214 | |||
163 | 215 | ||
164 | /* sched.text is aling to function alignment to secure we have same | 216 | /* sched.text is aling to function alignment to secure we have same |
165 | * address even at second ld pass when generating System.map */ | 217 | * address even at second ld pass when generating System.map */ |
@@ -184,11 +236,35 @@ | |||
184 | VMLINUX_SYMBOL(__kprobes_text_end) = .; | 236 | VMLINUX_SYMBOL(__kprobes_text_end) = .; |
185 | 237 | ||
186 | /* init and exit section handling */ | 238 | /* init and exit section handling */ |
187 | #define INIT_TEXT *(.init.text) | 239 | #define INIT_DATA \ |
188 | #define INIT_DATA *(.init.data) | 240 | *(.init.data) \ |
189 | #define EXIT_TEXT *(.exit.text) | 241 | DEV_DISCARD(init.data) \ |
190 | #define EXIT_DATA *(.exit.data) | 242 | DEV_DISCARD(init.rodata) \ |
243 | CPU_DISCARD(init.data) \ | ||
244 | CPU_DISCARD(init.rodata) \ | ||
245 | MEM_DISCARD(init.data) \ | ||
246 | MEM_DISCARD(init.rodata) | ||
247 | |||
248 | #define INIT_TEXT \ | ||
249 | *(.init.text) \ | ||
250 | DEV_DISCARD(init.text) \ | ||
251 | CPU_DISCARD(init.text) \ | ||
252 | MEM_DISCARD(init.text) | ||
253 | |||
254 | #define EXIT_DATA \ | ||
255 | *(.exit.data) \ | ||
256 | DEV_DISCARD(exit.data) \ | ||
257 | DEV_DISCARD(exit.rodata) \ | ||
258 | CPU_DISCARD(exit.data) \ | ||
259 | CPU_DISCARD(exit.rodata) \ | ||
260 | MEM_DISCARD(exit.data) \ | ||
261 | MEM_DISCARD(exit.rodata) | ||
191 | 262 | ||
263 | #define EXIT_TEXT \ | ||
264 | *(.exit.text) \ | ||
265 | DEV_DISCARD(exit.text) \ | ||
266 | CPU_DISCARD(exit.text) \ | ||
267 | MEM_DISCARD(exit.text) | ||
192 | 268 | ||
193 | /* DWARF debug sections. | 269 | /* DWARF debug sections. |
194 | Symbols in the DWARF debugging sections are relative to | 270 | Symbols in the DWARF debugging sections are relative to |
diff --git a/include/linux/init.h b/include/linux/init.h index 998076818402..dcb66c76bd48 100644 --- a/include/linux/init.h +++ b/include/linux/init.h | |||
@@ -60,18 +60,54 @@ | |||
60 | #define __exit_refok noinline __section(.exit.text.refok) | 60 | #define __exit_refok noinline __section(.exit.text.refok) |
61 | 61 | ||
62 | #ifdef MODULE | 62 | #ifdef MODULE |
63 | #define __exit __section(.exit.text) __cold | 63 | #define __exitused |
64 | #else | 64 | #else |
65 | #define __exit __attribute_used__ __section(.exit.text) __cold | 65 | #define __exitused __used |
66 | #endif | 66 | #endif |
67 | 67 | ||
68 | #define __exit __section(.exit.text) __exitused __cold | ||
69 | |||
70 | /* Used for HOTPLUG */ | ||
71 | #define __devinit __section(.devinit.text) __cold | ||
72 | #define __devinitdata __section(.devinit.data) | ||
73 | #define __devinitconst __section(.devinit.rodata) | ||
74 | #define __devexit __section(.devexit.text) __exitused __cold | ||
75 | #define __devexitdata __section(.devexit.data) | ||
76 | #define __devexitconst __section(.devexit.rodata) | ||
77 | |||
78 | /* Used for HOTPLUG_CPU */ | ||
79 | #define __cpuinit __section(.cpuinit.text) __cold | ||
80 | #define __cpuinitdata __section(.cpuinit.data) | ||
81 | #define __cpuinitconst __section(.cpuinit.rodata) | ||
82 | #define __cpuexit __section(.cpuexit.text) __exitused __cold | ||
83 | #define __cpuexitdata __section(.cpuexit.data) | ||
84 | #define __cpuexitconst __section(.cpuexit.rodata) | ||
85 | |||
86 | /* Used for MEMORY_HOTPLUG */ | ||
87 | #define __meminit __section(.meminit.text) __cold | ||
88 | #define __meminitdata __section(.meminit.data) | ||
89 | #define __meminitconst __section(.meminit.rodata) | ||
90 | #define __memexit __section(.memexit.text) __exitused __cold | ||
91 | #define __memexitdata __section(.memexit.data) | ||
92 | #define __memexitconst __section(.memexit.rodata) | ||
93 | |||
68 | /* For assembly routines */ | 94 | /* For assembly routines */ |
69 | #define __INIT .section ".init.text","ax" | 95 | #define __INIT .section ".init.text","ax" |
70 | #define __INIT_REFOK .section ".text.init.refok","ax" | 96 | #define __INIT_REFOK .section ".text.init.refok","ax" |
71 | #define __FINIT .previous | 97 | #define __FINIT .previous |
98 | |||
72 | #define __INITDATA .section ".init.data","aw" | 99 | #define __INITDATA .section ".init.data","aw" |
73 | #define __INITDATA_REFOK .section ".data.init.refok","aw" | 100 | #define __INITDATA_REFOK .section ".data.init.refok","aw" |
74 | 101 | ||
102 | #define __DEVINIT .section ".devinit.text", "ax" | ||
103 | #define __DEVINITDATA .section ".devinit.data", "aw" | ||
104 | |||
105 | #define __CPUINIT .section ".cpuinit.text", "ax" | ||
106 | #define __CPUINITDATA .section ".cpuinit.data", "aw" | ||
107 | |||
108 | #define __MEMINIT .section ".meminit.text", "ax" | ||
109 | #define __MEMINITDATA .section ".meminit.data", "aw" | ||
110 | |||
75 | #ifndef __ASSEMBLY__ | 111 | #ifndef __ASSEMBLY__ |
76 | /* | 112 | /* |
77 | * Used for initialization calls.. | 113 | * Used for initialization calls.. |
@@ -254,43 +290,6 @@ void __init parse_early_param(void); | |||
254 | #define __initdata_or_module __initdata | 290 | #define __initdata_or_module __initdata |
255 | #endif /*CONFIG_MODULES*/ | 291 | #endif /*CONFIG_MODULES*/ |
256 | 292 | ||
257 | #ifdef CONFIG_HOTPLUG | ||
258 | #define __devinit | ||
259 | #define __devinitdata | ||
260 | #define __devexit | ||
261 | #define __devexitdata | ||
262 | #else | ||
263 | #define __devinit __init | ||
264 | #define __devinitdata __initdata | ||
265 | #define __devexit __exit | ||
266 | #define __devexitdata __exitdata | ||
267 | #endif | ||
268 | |||
269 | #ifdef CONFIG_HOTPLUG_CPU | ||
270 | #define __cpuinit | ||
271 | #define __cpuinitdata | ||
272 | #define __cpuexit | ||
273 | #define __cpuexitdata | ||
274 | #else | ||
275 | #define __cpuinit __init | ||
276 | #define __cpuinitdata __initdata | ||
277 | #define __cpuexit __exit | ||
278 | #define __cpuexitdata __exitdata | ||
279 | #endif | ||
280 | |||
281 | #if defined(CONFIG_MEMORY_HOTPLUG) || defined(CONFIG_ACPI_HOTPLUG_MEMORY) \ | ||
282 | || defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE) | ||
283 | #define __meminit | ||
284 | #define __meminitdata | ||
285 | #define __memexit | ||
286 | #define __memexitdata | ||
287 | #else | ||
288 | #define __meminit __init | ||
289 | #define __meminitdata __initdata | ||
290 | #define __memexit __exit | ||
291 | #define __memexitdata __exitdata | ||
292 | #endif | ||
293 | |||
294 | /* Functions marked as __devexit may be discarded at kernel link time, depending | 293 | /* Functions marked as __devexit may be discarded at kernel link time, depending |
295 | on config options. Newer versions of binutils detect references from | 294 | on config options. Newer versions of binutils detect references from |
296 | retained sections to discarded sections and flag an error. Pointers to | 295 | retained sections to discarded sections and flag an error. Pointers to |
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 986513dcd700..730b321680cd 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c | |||
@@ -670,27 +670,41 @@ int match(const char *sym, const char * const pat[]) | |||
670 | static const char *section_white_list[] = | 670 | static const char *section_white_list[] = |
671 | { ".debug*", ".stab*", ".note*", ".got*", ".toc*", NULL }; | 671 | { ".debug*", ".stab*", ".note*", ".got*", ".toc*", NULL }; |
672 | 672 | ||
673 | #define INIT_DATA_SECTIONS ".init.data$" | 673 | #define ALL_INIT_DATA_SECTIONS \ |
674 | #define EXIT_DATA_SECTIONS ".exit.data$" | 674 | ".init.data$", ".devinit.data$", ".cpuinit.data$", ".meminit.data$" |
675 | #define ALL_EXIT_DATA_SECTIONS \ | ||
676 | ".exit.data$", ".devexit.data$", ".cpuexit.data$", ".memexit.data$" | ||
675 | 677 | ||
676 | #define INIT_TEXT_SECTIONS ".init.text$" | 678 | #define ALL_INIT_TEXT_SECTIONS \ |
677 | #define EXIT_TEXT_SECTIONS ".exit.text$" | 679 | ".init.text$", ".devinit.text$", ".cpuinit.text$", ".meminit.text$" |
680 | #define ALL_EXIT_TEXT_SECTIONS \ | ||
681 | ".exit.text$", ".devexit.text$", ".cpuexit.text$", ".memexit.text$" | ||
678 | 682 | ||
679 | #define INIT_SECTIONS INIT_DATA_SECTIONS, INIT_TEXT_SECTIONS | 683 | #define ALL_INIT_SECTIONS ALL_INIT_DATA_SECTIONS, ALL_INIT_TEXT_SECTIONS |
680 | #define EXIT_SECTIONS EXIT_DATA_SECTIONS, EXIT_TEXT_SECTIONS | 684 | #define ALL_EXIT_SECTIONS ALL_EXIT_DATA_SECTIONS, ALL_EXIT_TEXT_SECTIONS |
681 | 685 | ||
682 | #define DATA_SECTIONS ".data$", ".data.rel$" | 686 | #define DATA_SECTIONS ".data$", ".data.rel$" |
683 | #define TEXT_SECTIONS ".text$" | 687 | #define TEXT_SECTIONS ".text$" |
684 | 688 | ||
689 | #define INIT_SECTIONS ".init.data$", ".init.text$" | ||
690 | #define DEV_INIT_SECTIONS ".devinit.data$", ".devinit.text$" | ||
691 | #define CPU_INIT_SECTIONS ".cpuinit.data$", ".cpuinit.text$" | ||
692 | #define MEM_INIT_SECTIONS ".meminit.data$", ".meminit.text$" | ||
693 | |||
694 | #define EXIT_SECTIONS ".exit.data$", ".exit.text$" | ||
695 | #define DEV_EXIT_SECTIONS ".devexit.data$", ".devexit.text$" | ||
696 | #define CPU_EXIT_SECTIONS ".cpuexit.data$", ".cpuexit.text$" | ||
697 | #define MEM_EXIT_SECTIONS ".memexit.data$", ".memexit.text$" | ||
698 | |||
685 | /* init data sections */ | 699 | /* init data sections */ |
686 | static const char *init_data_sections[] = { INIT_DATA_SECTIONS, NULL }; | 700 | static const char *init_data_sections[] = { ALL_INIT_DATA_SECTIONS, NULL }; |
687 | 701 | ||
688 | /* all init sections */ | 702 | /* all init sections */ |
689 | static const char *init_sections[] = { INIT_SECTIONS, NULL }; | 703 | static const char *init_sections[] = { ALL_INIT_SECTIONS, NULL }; |
690 | 704 | ||
691 | /* All init and exit sections (code + data) */ | 705 | /* All init and exit sections (code + data) */ |
692 | static const char *init_exit_sections[] = | 706 | static const char *init_exit_sections[] = |
693 | {INIT_SECTIONS, EXIT_SECTIONS, NULL }; | 707 | {ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS, NULL }; |
694 | 708 | ||
695 | /* data section */ | 709 | /* data section */ |
696 | static const char *data_sections[] = { DATA_SECTIONS, NULL }; | 710 | static const char *data_sections[] = { DATA_SECTIONS, NULL }; |
@@ -734,22 +748,32 @@ const struct sectioncheck sectioncheck[] = { | |||
734 | */ | 748 | */ |
735 | { | 749 | { |
736 | .fromsec = { TEXT_SECTIONS, DATA_SECTIONS, NULL }, | 750 | .fromsec = { TEXT_SECTIONS, DATA_SECTIONS, NULL }, |
737 | .tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL } | 751 | .tosec = { ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS, NULL } |
752 | }, | ||
753 | /* Do not reference init code/data from devinit/cpuinit/meminit code/data */ | ||
754 | { | ||
755 | .fromsec = { DEV_INIT_SECTIONS, CPU_INIT_SECTIONS, MEM_INIT_SECTIONS, NULL }, | ||
756 | .tosec = { INIT_SECTIONS, NULL } | ||
757 | }, | ||
758 | /* Do not reference exit code/data from devexit/cpuexit/memexit code/data */ | ||
759 | { | ||
760 | .fromsec = { DEV_EXIT_SECTIONS, CPU_EXIT_SECTIONS, MEM_EXIT_SECTIONS, NULL }, | ||
761 | .tosec = { EXIT_SECTIONS, NULL } | ||
738 | }, | 762 | }, |
739 | /* Do not use exit code/data from init code */ | 763 | /* Do not use exit code/data from init code */ |
740 | { | 764 | { |
741 | .fromsec = { INIT_SECTIONS, NULL }, | 765 | .fromsec = { ALL_INIT_SECTIONS, NULL }, |
742 | .tosec = { EXIT_SECTIONS, NULL }, | 766 | .tosec = { ALL_EXIT_SECTIONS, NULL }, |
743 | }, | 767 | }, |
744 | /* Do not use init code/data from exit code */ | 768 | /* Do not use init code/data from exit code */ |
745 | { | 769 | { |
746 | .fromsec = { EXIT_SECTIONS, NULL }, | 770 | .fromsec = { ALL_EXIT_SECTIONS, NULL }, |
747 | .tosec = { INIT_SECTIONS, NULL } | 771 | .tosec = { ALL_INIT_SECTIONS, NULL } |
748 | }, | 772 | }, |
749 | /* Do not export init/exit functions or data */ | 773 | /* Do not export init/exit functions or data */ |
750 | { | 774 | { |
751 | .fromsec = { "__ksymtab*", NULL }, | 775 | .fromsec = { "__ksymtab*", NULL }, |
752 | .tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL } | 776 | .tosec = { ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS, NULL } |
753 | } | 777 | } |
754 | }; | 778 | }; |
755 | 779 | ||