xref: /linux/arch/powerpc/kernel/vmlinux.lds.S (revision 7ec7fb394298c212c30e063c57e0aa895efe9439)
1#ifdef CONFIG_PPC64
2#define PROVIDE32(x)	PROVIDE(__unused__##x)
3#else
4#define PROVIDE32(x)	PROVIDE(x)
5#endif
6#include <asm/page.h>
7#include <asm-generic/vmlinux.lds.h>
8#include <asm/cache.h>
9
10ENTRY(_stext)
11
12PHDRS {
13	kernel PT_LOAD FLAGS(7); /* RWX */
14	notes PT_NOTE FLAGS(0);
15	dummy PT_NOTE FLAGS(0);
16
17	/* binutils < 2.18 has a bug that makes it misbehave when taking an
18	   ELF file with all segments at load address 0 as input.  This
19	   happens when running "strip" on vmlinux, because of the AT() magic
20	   in this linker script.  People using GCC >= 4.2 won't run into
21	   this problem, because the "build-id" support will put some data
22	   into the "notes" segment (at a non-zero load address).
23
24	   To work around this, we force some data into both the "dummy"
25	   segment and the kernel segment, so the dummy segment will get a
26	   non-zero load address.  It's not enough to always create the
27	   "notes" segment, since if nothing gets assigned to it, its load
28	   address will be zero.  */
29}
30
31#ifdef CONFIG_PPC64
32OUTPUT_ARCH(powerpc:common64)
33jiffies = jiffies_64;
34#else
35OUTPUT_ARCH(powerpc:common)
36jiffies = jiffies_64 + 4;
37#endif
38SECTIONS
39{
40	/* Sections to be discarded. */
41	/DISCARD/ : {
42	*(.exitcall.exit)
43	EXIT_DATA
44	}
45
46	. = KERNELBASE;
47
48/*
49 * Text, read only data and other permanent read-only sections
50 */
51
52	/* Text and gots */
53	.text : AT(ADDR(.text) - LOAD_OFFSET) {
54		ALIGN_FUNCTION();
55		*(.text.head)
56		_text = .;
57		*(.text .fixup .text.init.refok .exit.text.refok __ftr_alt_*)
58		SCHED_TEXT
59		LOCK_TEXT
60		KPROBES_TEXT
61
62#ifdef CONFIG_PPC32
63		*(.got1)
64		__got2_start = .;
65		*(.got2)
66		__got2_end = .;
67#endif /* CONFIG_PPC32 */
68
69	} :kernel
70
71	. = ALIGN(PAGE_SIZE);
72	_etext = .;
73	PROVIDE32 (etext = .);
74
75	/* Read-only data */
76	RODATA
77
78	/* Exception & bug tables */
79	__ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
80		__start___ex_table = .;
81		*(__ex_table)
82		__stop___ex_table = .;
83	}
84
85	NOTES :kernel :notes
86
87	/* The dummy segment contents for the bug workaround mentioned above
88	   near PHDRS.  */
89	.dummy : AT(ADDR(.dummy) - LOAD_OFFSET) {
90		LONG(0xf177)
91	} :kernel :dummy
92
93/*
94 * Init sections discarded at runtime
95 */
96	. = ALIGN(PAGE_SIZE);
97	__init_begin = .;
98
99	.init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
100		_sinittext = .;
101		INIT_TEXT
102		_einittext = .;
103	} :kernel
104
105	/* .exit.text is discarded at runtime, not link time,
106	 * to deal with references from __bug_table
107	 */
108	.exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
109		EXIT_TEXT
110	}
111
112	.init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
113		INIT_DATA
114		__vtop_table_begin = .;
115		*(.vtop_fixup);
116		__vtop_table_end = .;
117		__ptov_table_begin = .;
118		*(.ptov_fixup);
119		__ptov_table_end = .;
120#ifdef CONFIG_PPC_ISERIES
121		__dt_strings_start = .;
122		*(.dt_strings);
123		__dt_strings_end = .;
124#endif
125	}
126
127	. = ALIGN(16);
128	.init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
129		__setup_start = .;
130		*(.init.setup)
131		__setup_end = .;
132	}
133
134	.initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
135		__initcall_start = .;
136		INITCALLS
137		__initcall_end = .;
138		}
139
140	.con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
141		__con_initcall_start = .;
142		*(.con_initcall.init)
143		__con_initcall_end = .;
144	}
145
146	SECURITY_INIT
147
148	. = ALIGN(8);
149	__ftr_fixup : AT(ADDR(__ftr_fixup) - LOAD_OFFSET) {
150		__start___ftr_fixup = .;
151		*(__ftr_fixup)
152		__stop___ftr_fixup = .;
153	}
154	. = ALIGN(8);
155	__mmu_ftr_fixup : AT(ADDR(__mmu_ftr_fixup) - LOAD_OFFSET) {
156		__start___mmu_ftr_fixup = .;
157		*(__mmu_ftr_fixup)
158		__stop___mmu_ftr_fixup = .;
159	}
160	. = ALIGN(8);
161	__lwsync_fixup : AT(ADDR(__lwsync_fixup) - LOAD_OFFSET) {
162		__start___lwsync_fixup = .;
163		*(__lwsync_fixup)
164		__stop___lwsync_fixup = .;
165	}
166#ifdef CONFIG_PPC64
167	. = ALIGN(8);
168	__fw_ftr_fixup : AT(ADDR(__fw_ftr_fixup) - LOAD_OFFSET) {
169		__start___fw_ftr_fixup = .;
170		*(__fw_ftr_fixup)
171		__stop___fw_ftr_fixup = .;
172	}
173#endif
174#ifdef CONFIG_BLK_DEV_INITRD
175	. = ALIGN(PAGE_SIZE);
176	.init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
177		__initramfs_start = .;
178		*(.init.ramfs)
179		__initramfs_end = .;
180	}
181#endif
182	. = ALIGN(PAGE_SIZE);
183	.data.percpu  : AT(ADDR(.data.percpu) - LOAD_OFFSET) {
184		__per_cpu_start = .;
185		*(.data.percpu)
186		*(.data.percpu.shared_aligned)
187		__per_cpu_end = .;
188	}
189
190	. = ALIGN(8);
191	.machine.desc : AT(ADDR(.machine.desc) - LOAD_OFFSET) {
192		__machine_desc_start = . ;
193		*(.machine.desc)
194		__machine_desc_end = . ;
195	}
196#ifdef CONFIG_RELOCATABLE
197	. = ALIGN(8);
198	.dynsym : AT(ADDR(.dynsym) - LOAD_OFFSET) { *(.dynsym) }
199	.dynstr : AT(ADDR(.dynstr) - LOAD_OFFSET) { *(.dynstr) }
200	.dynamic : AT(ADDR(.dynamic) - LOAD_OFFSET)
201	{
202		__dynamic_start = .;
203		*(.dynamic)
204	}
205	.hash : AT(ADDR(.hash) - LOAD_OFFSET) { *(.hash) }
206	.interp : AT(ADDR(.interp) - LOAD_OFFSET) { *(.interp) }
207	.rela.dyn : AT(ADDR(.rela.dyn) - LOAD_OFFSET)
208	{
209		__rela_dyn_start = .;
210		*(.rela*)
211	}
212#endif
213
214	/* freed after init ends here */
215	. = ALIGN(PAGE_SIZE);
216	__init_end = .;
217
218/*
219 * And now the various read/write data
220 */
221
222	. = ALIGN(PAGE_SIZE);
223	_sdata = .;
224
225#ifdef CONFIG_PPC32
226	.data : AT(ADDR(.data) - LOAD_OFFSET) {
227		DATA_DATA
228		*(.sdata)
229		*(.got.plt) *(.got)
230	}
231#else
232	.data : AT(ADDR(.data) - LOAD_OFFSET) {
233		DATA_DATA
234		*(.data.rel*)
235		*(.toc1)
236		*(.branch_lt)
237	}
238
239	.opd : AT(ADDR(.opd) - LOAD_OFFSET) {
240		*(.opd)
241	}
242
243	.got : AT(ADDR(.got) - LOAD_OFFSET) {
244		__toc_start = .;
245		*(.got)
246		*(.toc)
247	}
248#endif
249
250	. = ALIGN(PAGE_SIZE);
251	_edata  =  .;
252	PROVIDE32 (edata = .);
253
254	/* The initial task and kernel stack */
255#ifdef CONFIG_PPC32
256	. = ALIGN(8192);
257#else
258	. = ALIGN(16384);
259#endif
260	.data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
261		*(.data.init_task)
262	}
263
264	. = ALIGN(PAGE_SIZE);
265	.data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
266		*(.data.page_aligned)
267	}
268
269	.data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
270		*(.data.cacheline_aligned)
271	}
272
273	. = ALIGN(L1_CACHE_BYTES);
274	.data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
275		*(.data.read_mostly)
276	}
277
278	. = ALIGN(PAGE_SIZE);
279	.data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
280		__nosave_begin = .;
281		*(.data.nosave)
282		. = ALIGN(PAGE_SIZE);
283		__nosave_end = .;
284	}
285
286/*
287 * And finally the bss
288 */
289
290	.bss : AT(ADDR(.bss) - LOAD_OFFSET) {
291		__bss_start = .;
292		*(.sbss) *(.scommon)
293		*(.dynbss)
294		*(.bss)
295		*(COMMON)
296		__bss_stop = .;
297	}
298
299	. = ALIGN(PAGE_SIZE);
300	_end = . ;
301	PROVIDE32 (end = .);
302}
303