aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSam Ravnborg <sam@ravnborg.org>2008-01-20 14:07:28 -0500
committerSam Ravnborg <sam@ravnborg.org>2008-01-28 17:21:17 -0500
commiteb8f689046b857874e964463619f09df06d59fad (patch)
treeec726cd06764746a07689ede3b782c36a24d3e55
parentf3fe866d59d707c7a2bba0b23add078e19edb3dc (diff)
Use separate sections for __dev/__cpu/__mem code/data
Introducing separate sections for __dev* (HOTPLUG), __cpu* (HOTPLUG_CPU) and __mem* (MEMORY_HOTPLUG) allows us to do a much more reliable Section mismatch check in modpost. We are no longer dependent on the actual configuration of for example HOTPLUG. This has the effect that all users see much more Section mismatch warnings than before because they were almost all hidden when HOTPLUG was enabled. The advantage of this is that when building a piece of code then it is much more likely that the Section mismatch errors are spotted and the warnings will be felt less random of nature. Signed-off-by: Sam Ravnborg <sam@ravnborg.org> Cc: Greg KH <greg@kroah.com> Cc: Randy Dunlap <randy.dunlap@oracle.com> Cc: Adrian Bunk <bunk@kernel.org>
-rw-r--r--include/asm-generic/vmlinux.lds.h88
-rw-r--r--include/linux/init.h77
-rw-r--r--scripts/mod/modpost.c54
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[])
670static const char *section_white_list[] = 670static 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 */
686static const char *init_data_sections[] = { INIT_DATA_SECTIONS, NULL }; 700static const char *init_data_sections[] = { ALL_INIT_DATA_SECTIONS, NULL };
687 701
688/* all init sections */ 702/* all init sections */
689static const char *init_sections[] = { INIT_SECTIONS, NULL }; 703static 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) */
692static const char *init_exit_sections[] = 706static 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 */
696static const char *data_sections[] = { DATA_SECTIONS, NULL }; 710static 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