x86, vmlinux.lds: unify PHDRS
[safe/jmp/linux-2.6] / arch / x86 / kernel / vmlinux_64.lds.S
1 SECTIONS
2 {
3         . = __START_KERNEL;
4         phys_startup_64 = startup_64 - LOAD_OFFSET;
5
6         /* Text and read-only data */
7         .text :  AT(ADDR(.text) - LOAD_OFFSET) {
8                 _text = .;
9                 /* First the code that has to be first for bootstrapping */
10                 *(.text.head)
11                 _stext = .;
12                 /* Then the rest */
13                 TEXT_TEXT
14                 SCHED_TEXT
15                 LOCK_TEXT
16                 KPROBES_TEXT
17                 IRQENTRY_TEXT
18                 *(.fixup)
19                 *(.gnu.warning)
20                 /* End of text section */
21                 _etext = .;
22         } :text = 0x9090
23
24         NOTES :text :note
25
26         /* Exception table */
27         . = ALIGN(16);
28         __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
29                 __start___ex_table = .;
30                  *(__ex_table)
31                 __stop___ex_table = .;
32         } :text = 0x9090
33
34         RODATA
35
36         /* Align data segment to page size boundary */
37         . = ALIGN(PAGE_SIZE);
38         /* Data */
39         .data : AT(ADDR(.data) - LOAD_OFFSET) {
40                 DATA_DATA
41                 CONSTRUCTORS
42                 /* End of data section */
43                 _edata = .;
44         } :data
45
46
47         .data.cacheline_aligned :
48                 AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
49                 . = ALIGN(PAGE_SIZE);
50                 . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
51                 *(.data.cacheline_aligned)
52         }
53
54         . = ALIGN(CONFIG_X86_INTERNODE_CACHE_BYTES);
55         .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
56                 *(.data.read_mostly)
57         }
58
59 #define VSYSCALL_ADDR (-10*1024*1024)
60 #define VSYSCALL_PHYS_ADDR ((LOADADDR(.data.read_mostly) + \
61                             SIZEOF(.data.read_mostly) + 4095) & ~(4095))
62 #define VSYSCALL_VIRT_ADDR ((ADDR(.data.read_mostly) + \
63                             SIZEOF(.data.read_mostly) + 4095) & ~(4095))
64
65 #define VLOAD_OFFSET (VSYSCALL_ADDR - VSYSCALL_PHYS_ADDR)
66 #define VLOAD(x) (ADDR(x) - VLOAD_OFFSET)
67
68 #define VVIRT_OFFSET (VSYSCALL_ADDR - VSYSCALL_VIRT_ADDR)
69 #define VVIRT(x) (ADDR(x) - VVIRT_OFFSET)
70
71         . = VSYSCALL_ADDR;
72         .vsyscall_0 : AT(VSYSCALL_PHYS_ADDR) {
73                 *(.vsyscall_0)
74         } :user
75
76         __vsyscall_0 = VSYSCALL_VIRT_ADDR;
77
78         . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
79         .vsyscall_fn : AT(VLOAD(.vsyscall_fn)) {
80                 *(.vsyscall_fn)
81         }
82
83         . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
84         .vsyscall_gtod_data : AT(VLOAD(.vsyscall_gtod_data)) {
85                 *(.vsyscall_gtod_data)
86         }
87
88         vsyscall_gtod_data = VVIRT(.vsyscall_gtod_data);
89         .vsyscall_clock : AT(VLOAD(.vsyscall_clock)) {
90                 *(.vsyscall_clock)
91         }
92         vsyscall_clock = VVIRT(.vsyscall_clock);
93
94
95         .vsyscall_1 ADDR(.vsyscall_0) + 1024: AT(VLOAD(.vsyscall_1)) {
96                 *(.vsyscall_1)
97         }
98         .vsyscall_2 ADDR(.vsyscall_0) + 2048: AT(VLOAD(.vsyscall_2)) {
99                 *(.vsyscall_2)
100         }
101
102         .vgetcpu_mode : AT(VLOAD(.vgetcpu_mode)) {
103                 *(.vgetcpu_mode)
104         }
105         vgetcpu_mode = VVIRT(.vgetcpu_mode);
106
107         . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
108         .jiffies : AT(VLOAD(.jiffies)) {
109                 *(.jiffies)
110         }
111         jiffies = VVIRT(.jiffies);
112
113         .vsyscall_3 ADDR(.vsyscall_0) + 3072: AT(VLOAD(.vsyscall_3)) {
114                 *(.vsyscall_3)
115         }
116
117         . = VSYSCALL_VIRT_ADDR + PAGE_SIZE;
118
119 #undef VSYSCALL_ADDR
120 #undef VSYSCALL_PHYS_ADDR
121 #undef VSYSCALL_VIRT_ADDR
122 #undef VLOAD_OFFSET
123 #undef VLOAD
124 #undef VVIRT_OFFSET
125 #undef VVIRT
126
127         /* init_task */
128         .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
129                 . = ALIGN(THREAD_SIZE);
130                 *(.data.init_task)
131         } :data.init
132
133         .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
134                 . = ALIGN(PAGE_SIZE);
135                 *(.data.page_aligned)
136         }
137
138         .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
139                 /* might get freed after init */
140                 . = ALIGN(PAGE_SIZE);
141                 __smp_alt_begin = .;
142                 __smp_locks = .;
143                 *(.smp_locks)
144                 __smp_locks_end = .;
145                 . = ALIGN(PAGE_SIZE);
146                 __smp_alt_end = .;
147         }
148
149         /* Init code and data */
150         . = ALIGN(PAGE_SIZE);
151         __init_begin = .;       /* paired with __init_end */
152         .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
153                 _sinittext = .;
154                 INIT_TEXT
155                 _einittext = .;
156         }
157
158         .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
159                 __initdata_begin = .;
160                 INIT_DATA
161                 __initdata_end = .;
162         }
163
164         .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
165                 . = ALIGN(16);
166                 __setup_start = .;
167                 *(.init.setup)
168                 __setup_end = .;
169         }
170
171         .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
172                 __initcall_start = .;
173                 INITCALLS
174                 __initcall_end = .;
175         }
176
177         .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
178                 __con_initcall_start = .;
179                 *(.con_initcall.init)
180                 __con_initcall_end = .;
181         }
182
183         .x86_cpu_dev.init : AT(ADDR(.x86_cpu_dev.init) - LOAD_OFFSET) {
184                 __x86_cpu_dev_start = .;
185                 *(.x86_cpu_dev.init)
186                 __x86_cpu_dev_end = .;
187         }
188
189         SECURITY_INIT
190
191         . = ALIGN(8);
192         .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {
193                 __parainstructions = .;
194                 *(.parainstructions)
195                 __parainstructions_end = .;
196         }
197
198         .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
199                 . = ALIGN(8);
200                 __alt_instructions = .;
201                 *(.altinstructions)
202                 __alt_instructions_end = .;
203         }
204
205         .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
206                 *(.altinstr_replacement)
207         }
208
209         /*
210          * .exit.text is discard at runtime, not link time, to deal with
211          *  references from .altinstructions and .eh_frame
212          */
213         .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
214                 EXIT_TEXT
215         }
216
217         .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) {
218                 EXIT_DATA
219         }
220
221 #ifdef CONFIG_BLK_DEV_INITRD
222         . = ALIGN(PAGE_SIZE);
223         .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
224                 __initramfs_start = .;
225                 *(.init.ramfs)
226                 __initramfs_end = .;
227         }
228 #endif
229
230 #ifdef CONFIG_SMP
231         /*
232          * percpu offsets are zero-based on SMP.  PERCPU_VADDR() changes the
233          * output PHDR, so the next output section - __data_nosave - should
234          * start another section data.init2.  Also, pda should be at the head of
235          * percpu area.  Preallocate it and define the percpu offset symbol
236          * so that it can be accessed as a percpu variable.
237          */
238         . = ALIGN(PAGE_SIZE);
239         PERCPU_VADDR(0, :percpu)
240 #else
241         PERCPU(PAGE_SIZE)
242 #endif
243
244         . = ALIGN(PAGE_SIZE);
245         __init_end = .;
246
247         .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
248                 . = ALIGN(PAGE_SIZE);
249                 __nosave_begin = .;
250                 *(.data.nosave)
251                 . = ALIGN(PAGE_SIZE);
252                 __nosave_end = .;
253         } :data.init2
254         /* use another section data.init2, see PERCPU_VADDR() above */
255
256         .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
257                 . = ALIGN(PAGE_SIZE);
258                 __bss_start = .;                /* BSS */
259                 *(.bss.page_aligned)
260                 *(.bss)
261                 __bss_stop = .;
262         }
263
264         .brk : AT(ADDR(.brk) - LOAD_OFFSET) {
265                 . = ALIGN(PAGE_SIZE);
266                 __brk_base = .;
267                 . += 64 * 1024;         /* 64k alignment slop space */
268                 *(.brk_reservation)     /* areas brk users have reserved */
269                 __brk_limit = .;
270         }
271
272         _end = . ;
273
274         /* Sections to be discarded */
275         /DISCARD/ : {
276                 *(.exitcall.exit)
277                 *(.eh_frame)
278                 *(.discard)
279         }
280
281         STABS_DEBUG
282         DWARF_DEBUG
283 }