[PATCH] i386: Convert more absolute symbols to section relative
[linux-2.6] / arch / i386 / kernel / vmlinux.lds.S
1 /* ld script to make i386 Linux kernel
2  * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>;
3  *
4  * Don't define absolute symbols until and unless you know that symbol
5  * value is should remain constant even if kernel image is relocated
6  * at run time. Absolute symbols are not relocated. If symbol value should
7  * change if kernel is relocated, make the symbol section relative and
8  * put it inside the section definition.
9  */
10
11 /* Don't define absolute symbols until and unless you know that symbol
12  * value is should remain constant even if kernel image is relocated
13  * at run time. Absolute symbols are not relocated. If symbol value should
14  * change if kernel is relocated, make the symbol section relative and
15  * put it inside the section definition.
16  */
17 #define LOAD_OFFSET __PAGE_OFFSET
18
19 #include <asm-generic/vmlinux.lds.h>
20 #include <asm/thread_info.h>
21 #include <asm/page.h>
22 #include <asm/cache.h>
23 #include <asm/boot.h>
24
25 OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
26 OUTPUT_ARCH(i386)
27 ENTRY(phys_startup_32)
28 jiffies = jiffies_64;
29
30 PHDRS {
31         text PT_LOAD FLAGS(5);  /* R_E */
32         data PT_LOAD FLAGS(7);  /* RWE */
33         note PT_NOTE FLAGS(4);  /* R__ */
34 }
35 SECTIONS
36 {
37   . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR;
38   phys_startup_32 = startup_32 - LOAD_OFFSET;
39   /* read-only */
40   .text : AT(ADDR(.text) - LOAD_OFFSET) {
41         _text = .;                      /* Text and read-only data */
42         *(.text)
43         SCHED_TEXT
44         LOCK_TEXT
45         KPROBES_TEXT
46         *(.fixup)
47         *(.gnu.warning)
48         _etext = .;                     /* End of text section */
49   } :text = 0x9090
50
51   . = ALIGN(16);                /* Exception table */
52   __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
53         __start___ex_table = .;
54          *(__ex_table)
55         __stop___ex_table = .;
56   }
57
58   RODATA
59
60   . = ALIGN(4);
61   .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
62         __tracedata_start = .;
63         *(.tracedata)
64         __tracedata_end = .;
65   }
66
67   /* writeable */
68   . = ALIGN(4096);
69   .data : AT(ADDR(.data) - LOAD_OFFSET) {       /* Data */
70         *(.data)
71         CONSTRUCTORS
72         } :data
73
74   .paravirtprobe : AT(ADDR(.paravirtprobe) - LOAD_OFFSET) {
75         __start_paravirtprobe = .;
76         *(.paravirtprobe)
77         __stop_paravirtprobe = .;
78   }
79
80   . = ALIGN(4096);
81   .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
82         __nosave_begin = .;
83         *(.data.nosave)
84         . = ALIGN(4096);
85         __nosave_end = .;
86   }
87
88   . = ALIGN(4096);
89   .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
90         *(.data.idt)
91   }
92
93   . = ALIGN(32);
94   .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
95         *(.data.cacheline_aligned)
96   }
97
98   /* rarely changed data like cpu maps */
99   . = ALIGN(32);
100   .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
101         *(.data.read_mostly)
102         _edata = .;             /* End of data section */
103   }
104
105 #ifdef CONFIG_STACK_UNWIND
106   . = ALIGN(4);
107   .eh_frame : AT(ADDR(.eh_frame) - LOAD_OFFSET) {
108         __start_unwind = .;
109         *(.eh_frame)
110         __end_unwind = .;
111   }
112 #endif
113
114   . = ALIGN(THREAD_SIZE);       /* init_task */
115   .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
116         *(.data.init_task)
117   }
118
119   /* might get freed after init */
120   . = ALIGN(4096);
121   .smp_altinstructions : AT(ADDR(.smp_altinstructions) - LOAD_OFFSET) {
122         __smp_alt_begin = .;
123         __smp_alt_instructions = .;
124         *(.smp_altinstructions)
125         __smp_alt_instructions_end = .;
126   }
127   . = ALIGN(4);
128   .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
129         __smp_locks = .;
130         *(.smp_locks)
131         __smp_locks_end = .;
132   }
133   .smp_altinstr_replacement : AT(ADDR(.smp_altinstr_replacement) - LOAD_OFFSET) {
134         *(.smp_altinstr_replacement)
135         __smp_alt_end = .;
136   }
137   /* will be freed after init
138    * Following ALIGN() is required to make sure no other data falls on the
139    * same page where __smp_alt_end is pointing as that page might be freed
140    * after boot. Always make sure that ALIGN() directive is present after
141    * the section which contains __smp_alt_end.
142    */
143   . = ALIGN(4096);
144
145   /* will be freed after init */
146   . = ALIGN(4096);              /* Init code and data */
147   .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
148         __init_begin = .;
149         _sinittext = .;
150         *(.init.text)
151         _einittext = .;
152   }
153   .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) }
154   . = ALIGN(16);
155   .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
156         __setup_start = .;
157         *(.init.setup)
158         __setup_end = .;
159    }
160   .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
161         __initcall_start = .;
162         INITCALLS
163         __initcall_end = .;
164   }
165   .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
166         __con_initcall_start = .;
167         *(.con_initcall.init)
168         __con_initcall_end = .;
169   }
170   SECURITY_INIT
171   . = ALIGN(4);
172   .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
173         __alt_instructions = .;
174         *(.altinstructions)
175         __alt_instructions_end = .;
176   }
177   .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
178         *(.altinstr_replacement)
179   }
180   . = ALIGN(4);
181   .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {
182         __start_parainstructions = .;
183         *(.parainstructions)
184         __stop_parainstructions = .;
185   }
186   /* .exit.text is discard at runtime, not link time, to deal with references
187      from .altinstructions and .eh_frame */
188   .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) }
189   .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
190   . = ALIGN(4096);
191   .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
192         __initramfs_start = .;
193         *(.init.ramfs)
194         __initramfs_end = .;
195   }
196   . = ALIGN(L1_CACHE_BYTES);
197   .data.percpu  : AT(ADDR(.data.percpu) - LOAD_OFFSET) {
198         __per_cpu_start = .;
199         *(.data.percpu)
200         __per_cpu_end = .;
201   }
202   . = ALIGN(4096);
203   /* freed after init ends here */
204         
205   .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
206         __init_end = .;
207         __bss_start = .;                /* BSS */
208         *(.bss.page_aligned)
209         *(.bss)
210         . = ALIGN(4);
211         __bss_stop = .;
212         _end = . ;
213         /* This is where the kernel creates the early boot page tables */
214         . = ALIGN(4096);
215         pg0 = . ;
216   }
217
218   /* Sections to be discarded */
219   /DISCARD/ : {
220         *(.exitcall.exit)
221         }
222
223   STABS_DEBUG
224
225   DWARF_DEBUG
226
227   NOTES
228 }