Loading...
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifdef CONFIG_PPC64
3#define PROVIDE32(x) PROVIDE(__unused__##x)
4#else
5#define PROVIDE32(x) PROVIDE(x)
6#endif
7#include <asm/page.h>
8#include <asm-generic/vmlinux.lds.h>
9#include <asm/cache.h>
10#include <asm/thread_info.h>
11
12#if defined(CONFIG_STRICT_KERNEL_RWX) && !defined(CONFIG_PPC32)
13#define STRICT_ALIGN_SIZE (1 << 24)
14#else
15#define STRICT_ALIGN_SIZE PAGE_SIZE
16#endif
17
18ENTRY(_stext)
19
20PHDRS {
21 kernel PT_LOAD FLAGS(7); /* RWX */
22 notes PT_NOTE FLAGS(0);
23 dummy PT_NOTE FLAGS(0);
24
25 /* binutils < 2.18 has a bug that makes it misbehave when taking an
26 ELF file with all segments at load address 0 as input. This
27 happens when running "strip" on vmlinux, because of the AT() magic
28 in this linker script. People using GCC >= 4.2 won't run into
29 this problem, because the "build-id" support will put some data
30 into the "notes" segment (at a non-zero load address).
31
32 To work around this, we force some data into both the "dummy"
33 segment and the kernel segment, so the dummy segment will get a
34 non-zero load address. It's not enough to always create the
35 "notes" segment, since if nothing gets assigned to it, its load
36 address will be zero. */
37}
38
39#ifdef CONFIG_PPC64
40OUTPUT_ARCH(powerpc:common64)
41jiffies = jiffies_64;
42#else
43OUTPUT_ARCH(powerpc:common)
44jiffies = jiffies_64 + 4;
45#endif
46SECTIONS
47{
48 . = KERNELBASE;
49
50/*
51 * Text, read only data and other permanent read-only sections
52 */
53
54 _text = .;
55 _stext = .;
56
57 /*
58 * Head text.
59 * This needs to be in its own output section to avoid ld placing
60 * branch trampoline stubs randomly throughout the fixed sections,
61 * which it will do (even if the branch comes from another section)
62 * in order to optimize stub generation.
63 */
64 .head.text : AT(ADDR(.head.text) - LOAD_OFFSET) {
65#ifdef CONFIG_PPC64
66 KEEP(*(.head.text.first_256B));
67#ifdef CONFIG_PPC_BOOK3E
68#else
69 KEEP(*(.head.text.real_vectors));
70 *(.head.text.real_trampolines);
71 KEEP(*(.head.text.virt_vectors));
72 *(.head.text.virt_trampolines);
73# if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
74 KEEP(*(.head.data.fwnmi_page));
75# endif
76#endif
77#else /* !CONFIG_PPC64 */
78 HEAD_TEXT
79#endif
80 } :kernel
81
82 __head_end = .;
83
84#ifdef CONFIG_PPC64
85 /*
86 * BLOCK(0) overrides the default output section alignment because
87 * this needs to start right after .head.text in order for fixed
88 * section placement to work.
89 */
90 .text BLOCK(0) : AT(ADDR(.text) - LOAD_OFFSET) {
91#ifdef CONFIG_LD_HEAD_STUB_CATCH
92 *(.linker_stub_catch);
93 . = . ;
94#endif
95
96#else
97 .text : AT(ADDR(.text) - LOAD_OFFSET) {
98 ALIGN_FUNCTION();
99#endif
100 /* careful! __ftr_alt_* sections need to be close to .text */
101 *(.text.hot .text .text.fixup .text.unlikely .fixup __ftr_alt_* .ref.text);
102 SCHED_TEXT
103 CPUIDLE_TEXT
104 LOCK_TEXT
105 KPROBES_TEXT
106 IRQENTRY_TEXT
107 SOFTIRQENTRY_TEXT
108 /*
109 * -Os builds call FP save/restore functions. The powerpc64
110 * linker generates those on demand in the .sfpr section.
111 * .sfpr gets placed at the beginning of a group of input
112 * sections, which can break start-of-text offset if it is
113 * included with the main text sections, so put it by itself.
114 */
115 *(.sfpr);
116 MEM_KEEP(init.text)
117 MEM_KEEP(exit.text)
118
119#ifdef CONFIG_PPC32
120 *(.got1)
121 __got2_start = .;
122 *(.got2)
123 __got2_end = .;
124#endif /* CONFIG_PPC32 */
125
126 } :kernel
127
128 . = ALIGN(PAGE_SIZE);
129 _etext = .;
130 PROVIDE32 (etext = .);
131
132 /* Read-only data */
133 RO_DATA(PAGE_SIZE)
134
135#ifdef CONFIG_PPC64
136 . = ALIGN(8);
137 __stf_entry_barrier_fixup : AT(ADDR(__stf_entry_barrier_fixup) - LOAD_OFFSET) {
138 __start___stf_entry_barrier_fixup = .;
139 *(__stf_entry_barrier_fixup)
140 __stop___stf_entry_barrier_fixup = .;
141 }
142
143 . = ALIGN(8);
144 __stf_exit_barrier_fixup : AT(ADDR(__stf_exit_barrier_fixup) - LOAD_OFFSET) {
145 __start___stf_exit_barrier_fixup = .;
146 *(__stf_exit_barrier_fixup)
147 __stop___stf_exit_barrier_fixup = .;
148 }
149
150 . = ALIGN(8);
151 __rfi_flush_fixup : AT(ADDR(__rfi_flush_fixup) - LOAD_OFFSET) {
152 __start___rfi_flush_fixup = .;
153 *(__rfi_flush_fixup)
154 __stop___rfi_flush_fixup = .;
155 }
156#endif
157
158 EXCEPTION_TABLE(0)
159
160 NOTES :kernel :notes
161
162 /* The dummy segment contents for the bug workaround mentioned above
163 near PHDRS. */
164 .dummy : AT(ADDR(.dummy) - LOAD_OFFSET) {
165 LONG(0)
166 LONG(0)
167 LONG(0)
168 } :kernel :dummy
169
170/*
171 * Init sections discarded at runtime
172 */
173 . = ALIGN(STRICT_ALIGN_SIZE);
174 __init_begin = .;
175 INIT_TEXT_SECTION(PAGE_SIZE) :kernel
176
177 /* .exit.text is discarded at runtime, not link time,
178 * to deal with references from __bug_table
179 */
180 .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
181 EXIT_TEXT
182 }
183
184 .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
185 INIT_DATA
186 __vtop_table_begin = .;
187 *(.vtop_fixup);
188 __vtop_table_end = .;
189 __ptov_table_begin = .;
190 *(.ptov_fixup);
191 __ptov_table_end = .;
192 }
193
194 .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
195 INIT_SETUP(16)
196 }
197
198 .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
199 INIT_CALLS
200 }
201
202 .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
203 CON_INITCALL
204 }
205
206 SECURITY_INIT
207
208 . = ALIGN(8);
209 __ftr_fixup : AT(ADDR(__ftr_fixup) - LOAD_OFFSET) {
210 __start___ftr_fixup = .;
211 *(__ftr_fixup)
212 __stop___ftr_fixup = .;
213 }
214 . = ALIGN(8);
215 __mmu_ftr_fixup : AT(ADDR(__mmu_ftr_fixup) - LOAD_OFFSET) {
216 __start___mmu_ftr_fixup = .;
217 *(__mmu_ftr_fixup)
218 __stop___mmu_ftr_fixup = .;
219 }
220 . = ALIGN(8);
221 __lwsync_fixup : AT(ADDR(__lwsync_fixup) - LOAD_OFFSET) {
222 __start___lwsync_fixup = .;
223 *(__lwsync_fixup)
224 __stop___lwsync_fixup = .;
225 }
226#ifdef CONFIG_PPC64
227 . = ALIGN(8);
228 __fw_ftr_fixup : AT(ADDR(__fw_ftr_fixup) - LOAD_OFFSET) {
229 __start___fw_ftr_fixup = .;
230 *(__fw_ftr_fixup)
231 __stop___fw_ftr_fixup = .;
232 }
233#endif
234 .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
235 INIT_RAM_FS
236 }
237
238 PERCPU_SECTION(L1_CACHE_BYTES)
239
240 . = ALIGN(8);
241 .machine.desc : AT(ADDR(.machine.desc) - LOAD_OFFSET) {
242 __machine_desc_start = . ;
243 *(.machine.desc)
244 __machine_desc_end = . ;
245 }
246#ifdef CONFIG_RELOCATABLE
247 . = ALIGN(8);
248 .dynsym : AT(ADDR(.dynsym) - LOAD_OFFSET)
249 {
250#ifdef CONFIG_PPC32
251 __dynamic_symtab = .;
252#endif
253 *(.dynsym)
254 }
255 .dynstr : AT(ADDR(.dynstr) - LOAD_OFFSET) { *(.dynstr) }
256 .dynamic : AT(ADDR(.dynamic) - LOAD_OFFSET)
257 {
258 __dynamic_start = .;
259 *(.dynamic)
260 }
261 .hash : AT(ADDR(.hash) - LOAD_OFFSET) { *(.hash) }
262 .interp : AT(ADDR(.interp) - LOAD_OFFSET) { *(.interp) }
263 .rela.dyn : AT(ADDR(.rela.dyn) - LOAD_OFFSET)
264 {
265 __rela_dyn_start = .;
266 *(.rela*)
267 }
268#endif
269 /* .exit.data is discarded at runtime, not link time,
270 * to deal with references from .exit.text
271 */
272 .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) {
273 EXIT_DATA
274 }
275
276 /* freed after init ends here */
277 . = ALIGN(PAGE_SIZE);
278 __init_end = .;
279
280/*
281 * And now the various read/write data
282 */
283
284 . = ALIGN(PAGE_SIZE);
285 _sdata = .;
286
287#ifdef CONFIG_PPC32
288 .data : AT(ADDR(.data) - LOAD_OFFSET) {
289 DATA_DATA
290 *(.data.rel*)
291 *(.sdata)
292 *(.sdata2)
293 *(.got.plt) *(.got)
294 *(.plt)
295 }
296#else
297 .data : AT(ADDR(.data) - LOAD_OFFSET) {
298 DATA_DATA
299 *(.data.rel*)
300 *(.toc1)
301 *(.branch_lt)
302 }
303
304 .opd : AT(ADDR(.opd) - LOAD_OFFSET) {
305 __start_opd = .;
306 *(.opd)
307 __end_opd = .;
308 }
309
310 . = ALIGN(256);
311 .got : AT(ADDR(.got) - LOAD_OFFSET) {
312 __toc_start = .;
313#ifndef CONFIG_RELOCATABLE
314 __prom_init_toc_start = .;
315 arch/powerpc/kernel/prom_init.o*(.toc .got)
316 __prom_init_toc_end = .;
317#endif
318 *(.got)
319 *(.toc)
320 }
321#endif
322
323 /* The initial task and kernel stack */
324 INIT_TASK_DATA_SECTION(THREAD_SIZE)
325
326 .data..page_aligned : AT(ADDR(.data..page_aligned) - LOAD_OFFSET) {
327 PAGE_ALIGNED_DATA(PAGE_SIZE)
328 }
329
330 .data..cacheline_aligned : AT(ADDR(.data..cacheline_aligned) - LOAD_OFFSET) {
331 CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES)
332 }
333
334 .data..read_mostly : AT(ADDR(.data..read_mostly) - LOAD_OFFSET) {
335 READ_MOSTLY_DATA(L1_CACHE_BYTES)
336 }
337
338 . = ALIGN(PAGE_SIZE);
339 .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
340 NOSAVE_DATA
341 }
342
343 BUG_TABLE
344
345 . = ALIGN(PAGE_SIZE);
346 _edata = .;
347 PROVIDE32 (edata = .);
348
349/*
350 * And finally the bss
351 */
352
353 BSS_SECTION(0, 0, 0)
354
355 . = ALIGN(PAGE_SIZE);
356 _end = . ;
357 PROVIDE32 (end = .);
358
359 STABS_DEBUG
360
361 DWARF_DEBUG
362
363 DISCARDS
364 /DISCARD/ : {
365 *(*.EMB.apuinfo)
366 *(.glink .iplt .plt .rela* .comment)
367 *(.gnu.version*)
368 *(.gnu.attributes)
369 *(.eh_frame)
370 }
371}
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#include <asm/thread_info.h>
10
11ENTRY(_stext)
12
13PHDRS {
14 kernel PT_LOAD FLAGS(7); /* RWX */
15 notes PT_NOTE FLAGS(0);
16 dummy PT_NOTE FLAGS(0);
17
18 /* binutils < 2.18 has a bug that makes it misbehave when taking an
19 ELF file with all segments at load address 0 as input. This
20 happens when running "strip" on vmlinux, because of the AT() magic
21 in this linker script. People using GCC >= 4.2 won't run into
22 this problem, because the "build-id" support will put some data
23 into the "notes" segment (at a non-zero load address).
24
25 To work around this, we force some data into both the "dummy"
26 segment and the kernel segment, so the dummy segment will get a
27 non-zero load address. It's not enough to always create the
28 "notes" segment, since if nothing gets assigned to it, its load
29 address will be zero. */
30}
31
32#ifdef CONFIG_PPC64
33OUTPUT_ARCH(powerpc:common64)
34jiffies = jiffies_64;
35#else
36OUTPUT_ARCH(powerpc:common)
37jiffies = jiffies_64 + 4;
38#endif
39SECTIONS
40{
41 . = KERNELBASE;
42
43/*
44 * Text, read only data and other permanent read-only sections
45 */
46
47 _text = .;
48 _stext = .;
49
50 /*
51 * Head text.
52 * This needs to be in its own output section to avoid ld placing
53 * branch trampoline stubs randomly throughout the fixed sections,
54 * which it will do (even if the branch comes from another section)
55 * in order to optimize stub generation.
56 */
57 .head.text : AT(ADDR(.head.text) - LOAD_OFFSET) {
58#ifdef CONFIG_PPC64
59 KEEP(*(.head.text.first_256B));
60#ifdef CONFIG_PPC_BOOK3E
61# define END_FIXED 0x100
62#else
63 KEEP(*(.head.text.real_vectors));
64 *(.head.text.real_trampolines);
65 KEEP(*(.head.text.virt_vectors));
66 *(.head.text.virt_trampolines);
67# if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
68 KEEP(*(.head.data.fwnmi_page));
69# define END_FIXED 0x8000
70# else
71# define END_FIXED 0x7000
72# endif
73#endif
74 ASSERT((. == END_FIXED), "vmlinux.lds.S: fixed section overflow error");
75#else /* !CONFIG_PPC64 */
76 HEAD_TEXT
77#endif
78 } :kernel
79
80 /*
81 * If the build dies here, it's likely code in head_64.S is referencing
82 * labels it can't reach, and the linker inserting stubs without the
83 * assembler's knowledge. To debug, remove the above assert and
84 * rebuild. Look for branch stubs in the fixed section region.
85 *
86 * Linker stub generation could be allowed in "trampoline"
87 * sections if absolutely necessary, but this would require
88 * some rework of the fixed sections. Before resorting to this,
89 * consider references that have sufficient addressing range,
90 * (e.g., hand coded trampolines) so the linker does not have
91 * to add stubs.
92 *
93 * Linker stubs at the top of the main text section are currently not
94 * detected, and will result in a crash at boot due to offsets being
95 * wrong.
96 */
97#ifdef CONFIG_PPC64
98 /*
99 * BLOCK(0) overrides the default output section alignment because
100 * this needs to start right after .head.text in order for fixed
101 * section placement to work.
102 */
103 .text BLOCK(0) : AT(ADDR(.text) - LOAD_OFFSET) {
104#else
105 .text : AT(ADDR(.text) - LOAD_OFFSET) {
106 ALIGN_FUNCTION();
107#endif
108 /* careful! __ftr_alt_* sections need to be close to .text */
109 *(.text .fixup __ftr_alt_* .ref.text)
110 SCHED_TEXT
111 CPUIDLE_TEXT
112 LOCK_TEXT
113 KPROBES_TEXT
114 IRQENTRY_TEXT
115 SOFTIRQENTRY_TEXT
116 MEM_KEEP(init.text)
117 MEM_KEEP(exit.text)
118
119#ifdef CONFIG_PPC32
120 *(.got1)
121 __got2_start = .;
122 *(.got2)
123 __got2_end = .;
124#endif /* CONFIG_PPC32 */
125
126 } :kernel
127
128 . = ALIGN(PAGE_SIZE);
129 _etext = .;
130 PROVIDE32 (etext = .);
131
132 /* Read-only data */
133 RODATA
134
135 EXCEPTION_TABLE(0)
136
137 NOTES :kernel :notes
138
139 /* The dummy segment contents for the bug workaround mentioned above
140 near PHDRS. */
141 .dummy : AT(ADDR(.dummy) - LOAD_OFFSET) {
142 LONG(0)
143 LONG(0)
144 LONG(0)
145 } :kernel :dummy
146
147/*
148 * Init sections discarded at runtime
149 */
150 . = ALIGN(PAGE_SIZE);
151 __init_begin = .;
152 INIT_TEXT_SECTION(PAGE_SIZE) :kernel
153
154 /* .exit.text is discarded at runtime, not link time,
155 * to deal with references from __bug_table
156 */
157 .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
158 EXIT_TEXT
159 }
160
161 .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
162 INIT_DATA
163 __vtop_table_begin = .;
164 *(.vtop_fixup);
165 __vtop_table_end = .;
166 __ptov_table_begin = .;
167 *(.ptov_fixup);
168 __ptov_table_end = .;
169 }
170
171 .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
172 INIT_SETUP(16)
173 }
174
175 .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
176 INIT_CALLS
177 }
178
179 .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
180 CON_INITCALL
181 }
182
183 SECURITY_INIT
184
185 . = ALIGN(8);
186 __ftr_fixup : AT(ADDR(__ftr_fixup) - LOAD_OFFSET) {
187 __start___ftr_fixup = .;
188 *(__ftr_fixup)
189 __stop___ftr_fixup = .;
190 }
191 . = ALIGN(8);
192 __mmu_ftr_fixup : AT(ADDR(__mmu_ftr_fixup) - LOAD_OFFSET) {
193 __start___mmu_ftr_fixup = .;
194 *(__mmu_ftr_fixup)
195 __stop___mmu_ftr_fixup = .;
196 }
197 . = ALIGN(8);
198 __lwsync_fixup : AT(ADDR(__lwsync_fixup) - LOAD_OFFSET) {
199 __start___lwsync_fixup = .;
200 *(__lwsync_fixup)
201 __stop___lwsync_fixup = .;
202 }
203#ifdef CONFIG_PPC64
204 . = ALIGN(8);
205 __fw_ftr_fixup : AT(ADDR(__fw_ftr_fixup) - LOAD_OFFSET) {
206 __start___fw_ftr_fixup = .;
207 *(__fw_ftr_fixup)
208 __stop___fw_ftr_fixup = .;
209 }
210#endif
211 .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
212 INIT_RAM_FS
213 }
214
215 PERCPU_SECTION(L1_CACHE_BYTES)
216
217 . = ALIGN(8);
218 .machine.desc : AT(ADDR(.machine.desc) - LOAD_OFFSET) {
219 __machine_desc_start = . ;
220 *(.machine.desc)
221 __machine_desc_end = . ;
222 }
223#ifdef CONFIG_RELOCATABLE
224 . = ALIGN(8);
225 .dynsym : AT(ADDR(.dynsym) - LOAD_OFFSET)
226 {
227#ifdef CONFIG_PPC32
228 __dynamic_symtab = .;
229#endif
230 *(.dynsym)
231 }
232 .dynstr : AT(ADDR(.dynstr) - LOAD_OFFSET) { *(.dynstr) }
233 .dynamic : AT(ADDR(.dynamic) - LOAD_OFFSET)
234 {
235 __dynamic_start = .;
236 *(.dynamic)
237 }
238 .hash : AT(ADDR(.hash) - LOAD_OFFSET) { *(.hash) }
239 .interp : AT(ADDR(.interp) - LOAD_OFFSET) { *(.interp) }
240 .rela.dyn : AT(ADDR(.rela.dyn) - LOAD_OFFSET)
241 {
242 __rela_dyn_start = .;
243 *(.rela*)
244 }
245#endif
246 /* .exit.data is discarded at runtime, not link time,
247 * to deal with references from .exit.text
248 */
249 .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) {
250 EXIT_DATA
251 }
252
253 /* freed after init ends here */
254 . = ALIGN(PAGE_SIZE);
255 __init_end = .;
256
257/*
258 * And now the various read/write data
259 */
260
261 . = ALIGN(PAGE_SIZE);
262 _sdata = .;
263
264#ifdef CONFIG_PPC32
265 .data : AT(ADDR(.data) - LOAD_OFFSET) {
266 DATA_DATA
267 *(.sdata)
268 *(.got.plt) *(.got)
269 }
270#else
271 .data : AT(ADDR(.data) - LOAD_OFFSET) {
272 DATA_DATA
273 *(.data.rel*)
274 *(.toc1)
275 *(.branch_lt)
276 }
277
278 .opd : AT(ADDR(.opd) - LOAD_OFFSET) {
279 *(.opd)
280 }
281
282 . = ALIGN(256);
283 .got : AT(ADDR(.got) - LOAD_OFFSET) {
284 __toc_start = .;
285#ifndef CONFIG_RELOCATABLE
286 __prom_init_toc_start = .;
287 arch/powerpc/kernel/prom_init.o*(.toc .got)
288 __prom_init_toc_end = .;
289#endif
290 *(.got)
291 *(.toc)
292 }
293#endif
294
295 /* The initial task and kernel stack */
296 INIT_TASK_DATA_SECTION(THREAD_SIZE)
297
298 .data..page_aligned : AT(ADDR(.data..page_aligned) - LOAD_OFFSET) {
299 PAGE_ALIGNED_DATA(PAGE_SIZE)
300 }
301
302 .data..cacheline_aligned : AT(ADDR(.data..cacheline_aligned) - LOAD_OFFSET) {
303 CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES)
304 }
305
306 .data..read_mostly : AT(ADDR(.data..read_mostly) - LOAD_OFFSET) {
307 READ_MOSTLY_DATA(L1_CACHE_BYTES)
308 }
309
310 . = ALIGN(PAGE_SIZE);
311 .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
312 NOSAVE_DATA
313 }
314
315 . = ALIGN(PAGE_SIZE);
316 _edata = .;
317 PROVIDE32 (edata = .);
318
319/*
320 * And finally the bss
321 */
322
323 BSS_SECTION(0, 0, 0)
324
325 . = ALIGN(PAGE_SIZE);
326 _end = . ;
327 PROVIDE32 (end = .);
328
329 /* Sections to be discarded. */
330 DISCARDS
331}