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