xref: /linux/arch/arm64/kernel/vmlinux.lds.S (revision 39d5ca62a3dab7d162d49eb60b14cdd46138590f)
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * ld script to make ARM Linux kernel
4 * taken from the i386 version by Russell King
5 * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
6 */
7
8#include <asm/hyp_image.h>
9#ifdef CONFIG_KVM
10#define HYPERVISOR_EXTABLE					\
11	. = ALIGN(SZ_8);					\
12	__start___kvm_ex_table = .;				\
13	*(__kvm_ex_table)					\
14	__stop___kvm_ex_table = .;
15
16#ifdef CONFIG_NVHE_EL2_TRACING
17#define HYPERVISOR_EVENT_IDS 					\
18	. = ALIGN(PAGE_SIZE);					\
19	__hyp_event_ids_start = .;				\
20	*(HYP_SECTION_NAME(.event_ids))				\
21	__hyp_event_ids_end = .;
22#else
23#define HYPERVISOR_EVENT_IDS
24#endif
25
26#define HYPERVISOR_RODATA_SECTIONS				\
27	HYP_SECTION_NAME(.rodata) : {				\
28		. = ALIGN(PAGE_SIZE);				\
29		__hyp_rodata_start = .;				\
30		*(HYP_SECTION_NAME(.data..ro_after_init))	\
31		*(HYP_SECTION_NAME(.rodata))			\
32		HYPERVISOR_EVENT_IDS				\
33		. = ALIGN(PAGE_SIZE);				\
34		__hyp_rodata_end = .;				\
35	}
36
37#define HYPERVISOR_DATA_SECTION					\
38	HYP_SECTION_NAME(.data) : {				\
39		. = ALIGN(PAGE_SIZE);				\
40		__hyp_data_start = .;				\
41		*(HYP_SECTION_NAME(.data))			\
42		. = ALIGN(PAGE_SIZE);				\
43		__hyp_data_end = .;				\
44	}
45
46#define HYPERVISOR_PERCPU_SECTION				\
47	. = ALIGN(PAGE_SIZE);					\
48	HYP_SECTION_NAME(.data..percpu) : {			\
49		*(HYP_SECTION_NAME(.data..percpu))		\
50	}
51
52#define HYPERVISOR_RELOC_SECTION				\
53	.hyp.reloc : ALIGN(4) {					\
54		__hyp_reloc_begin = .;				\
55		*(.hyp.reloc)					\
56		__hyp_reloc_end = .;				\
57	}
58
59#define BSS_FIRST_SECTIONS					\
60	__hyp_bss_start = .;					\
61	*(HYP_SECTION_NAME(.bss))				\
62	. = ALIGN(PAGE_SIZE);					\
63	__hyp_bss_end = .;
64
65/*
66 * We require that __hyp_bss_start and __bss_start are aligned, and enforce it
67 * with an assertion. But the BSS_SECTION macro places an empty .sbss section
68 * between them, which can in some cases cause the linker to misalign them. To
69 * work around the issue, force a page alignment for __bss_start.
70 */
71#define SBSS_ALIGN			PAGE_SIZE
72#else /* CONFIG_KVM */
73#define HYPERVISOR_EXTABLE
74#define HYPERVISOR_RODATA_SECTIONS
75#define HYPERVISOR_DATA_SECTION
76#define HYPERVISOR_PERCPU_SECTION
77#define HYPERVISOR_RELOC_SECTION
78#define SBSS_ALIGN			0
79#endif
80
81#define RO_EXCEPTION_TABLE_ALIGN	4
82#define RUNTIME_DISCARD_EXIT
83
84#include <asm-generic/vmlinux.lds.h>
85#include <asm/cache.h>
86#include <asm/kernel-pgtable.h>
87#include <asm/kexec.h>
88#include <asm/memory.h>
89#include <asm/page.h>
90
91#include "image.h"
92
93OUTPUT_ARCH(aarch64)
94ENTRY(_text)
95
96jiffies = jiffies_64;
97
98#define HYPERVISOR_TEXT					\
99	. = ALIGN(PAGE_SIZE);				\
100	__hyp_idmap_text_start = .;			\
101	*(.hyp.idmap.text)				\
102	__hyp_idmap_text_end = .;			\
103	__hyp_text_start = .;				\
104	*(.hyp.text)					\
105	HYPERVISOR_EXTABLE				\
106	. = ALIGN(PAGE_SIZE);				\
107	__hyp_text_end = .;
108
109#define IDMAP_TEXT					\
110	. = ALIGN(SZ_4K);				\
111	__idmap_text_start = .;				\
112	*(.idmap.text)					\
113	__idmap_text_end = .;
114
115#ifdef CONFIG_HIBERNATION
116#define HIBERNATE_TEXT					\
117	ALIGN_FUNCTION();				\
118	__hibernate_exit_text_start = .;		\
119	*(.hibernate_exit.text)				\
120	__hibernate_exit_text_end = .;
121#else
122#define HIBERNATE_TEXT
123#endif
124
125#ifdef CONFIG_KEXEC_CORE
126#define KEXEC_TEXT					\
127	ALIGN_FUNCTION();				\
128	__relocate_new_kernel_start = .;		\
129	*(.kexec_relocate.text)				\
130	__relocate_new_kernel_end = .;
131#else
132#define KEXEC_TEXT
133#endif
134
135#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
136#define TRAMP_TEXT					\
137	. = ALIGN(PAGE_SIZE);				\
138	__entry_tramp_text_start = .;			\
139	*(.entry.tramp.text)				\
140	. = ALIGN(PAGE_SIZE);				\
141	__entry_tramp_text_end = .;			\
142	*(.entry.tramp.rodata)
143#else
144#define TRAMP_TEXT
145#endif
146
147#ifdef CONFIG_UNWIND_TABLES
148#define UNWIND_DATA_SECTIONS				\
149	.eh_frame : {					\
150		__pi___eh_frame_start = .;		\
151		*(.eh_frame)				\
152		__pi___eh_frame_end = .;		\
153	}
154#else
155#define UNWIND_DATA_SECTIONS
156#endif
157
158/*
159 * The size of the PE/COFF section that covers the kernel image, which
160 * runs from _stext to _edata, must be a round multiple of the PE/COFF
161 * FileAlignment, which we set to its minimum value of 0x200. '_stext'
162 * itself is 4 KB aligned, so padding out _edata to a 0x200 aligned
163 * boundary should be sufficient.
164 */
165PECOFF_FILE_ALIGNMENT = 0x200;
166
167#ifdef CONFIG_EFI
168#define PECOFF_EDATA_PADDING	\
169	.pecoff_edata_padding : { BYTE(0); . = ALIGN(PECOFF_FILE_ALIGNMENT); }
170#else
171#define PECOFF_EDATA_PADDING
172#endif
173
174SECTIONS
175{
176	/*
177	 * XXX: The linker does not define how output sections are
178	 * assigned to input sections when there are multiple statements
179	 * matching the same input section name.  There is no documented
180	 * order of matching.
181	 */
182	DISCARDS
183	/DISCARD/ : {
184		*(.interp .dynamic)
185		*(.dynsym .dynstr .hash .gnu.hash)
186		*(.ARM.attributes)
187	}
188
189	. = KIMAGE_VADDR;
190
191	.head.text : {
192		_text = .;
193		HEAD_TEXT
194	}
195	.text : ALIGN(SEGMENT_ALIGN) {	/* Real text segment		*/
196		_stext = .;		/* Text and read-only data	*/
197			IRQENTRY_TEXT
198			SOFTIRQENTRY_TEXT
199			ENTRY_TEXT
200			TEXT_TEXT
201			SCHED_TEXT
202			LOCK_TEXT
203			KPROBES_TEXT
204			HYPERVISOR_TEXT
205			*(.gnu.warning)
206	}
207
208	. = ALIGN(SEGMENT_ALIGN);
209	_etext = .;			/* End of text section */
210
211	/* everything from this point to __init_begin will be marked RO NX */
212	RO_DATA(PAGE_SIZE)
213
214	HYPERVISOR_RODATA_SECTIONS
215
216	.got : { *(.got) }
217	/*
218	 * Make sure that the .got.plt is either completely empty or it
219	 * contains only the lazy dispatch entries.
220	 */
221	.got.plt : { *(.got.plt) }
222	ASSERT(SIZEOF(.got.plt) == 0 || SIZEOF(.got.plt) == 0x18,
223	       "Unexpected GOT/PLT entries detected!")
224
225	/* code sections that are never executed via the kernel mapping */
226	.rodata.text : {
227		TRAMP_TEXT
228		HIBERNATE_TEXT
229		KEXEC_TEXT
230		IDMAP_TEXT
231		. = ALIGN(PAGE_SIZE);
232	}
233
234	idmap_pg_dir = .;
235	. += PAGE_SIZE;
236
237#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
238	tramp_pg_dir = .;
239	. += PAGE_SIZE;
240#endif
241
242	reserved_pg_dir = .;
243	. += PAGE_SIZE;
244
245	swapper_pg_dir = .;
246	. += PAGE_SIZE;
247
248	. = ALIGN(SEGMENT_ALIGN);
249	__init_begin = .;
250	__inittext_begin = .;
251
252	INIT_TEXT_SECTION(8)
253
254	__exittext_begin = .;
255	.exit.text : {
256		EXIT_TEXT
257	}
258	__exittext_end = .;
259
260	. = ALIGN(4);
261	.altinstructions : {
262		__alt_instructions = .;
263		*(.altinstructions)
264		__alt_instructions_end = .;
265	}
266
267	UNWIND_DATA_SECTIONS
268
269	. = ALIGN(SEGMENT_ALIGN);
270	__inittext_end = .;
271	__initdata_begin = .;
272
273	__pi_init_idmap_pg_dir = .;
274	. += INIT_IDMAP_DIR_SIZE;
275	__pi_init_idmap_pg_end = .;
276
277	.init.data : {
278		INIT_DATA
279		INIT_SETUP(16)
280		INIT_CALLS
281		CON_INITCALL
282		INIT_RAM_FS
283		*(.init.altinstructions .init.bss)	/* from the EFI stub */
284	}
285	.exit.data : {
286		EXIT_DATA
287	}
288
289	RUNTIME_CONST_VARIABLES
290
291	PERCPU_SECTION(L1_CACHE_BYTES)
292	HYPERVISOR_PERCPU_SECTION
293
294	HYPERVISOR_RELOC_SECTION
295
296	.rela.dyn : ALIGN(8) {
297		__pi_rela_start = .;
298		*(.rela .rela*)
299		__pi_rela_end = .;
300	}
301
302	.relr.dyn : ALIGN(8) {
303		__pi_relr_start = .;
304		*(.relr.dyn)
305		__pi_relr_end = .;
306	}
307
308	. = ALIGN(SEGMENT_ALIGN);
309	__initdata_end = .;
310	__init_end = .;
311
312	.data.rel.ro : { *(.data.rel.ro) }
313	ASSERT(SIZEOF(.data.rel.ro) == 0, "Unexpected RELRO detected!")
314
315	_data = .;
316	_sdata = .;
317	RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_ALIGN)
318
319	HYPERVISOR_DATA_SECTION
320
321#ifdef CONFIG_NVHE_EL2_TRACING
322	.data.hyp_events : {
323		__hyp_events_start = .;
324		*(SORT(_hyp_events.*))
325		__hyp_events_end = .;
326	}
327#endif
328	/*
329	 * Data written with the MMU off but read with the MMU on requires
330	 * cache lines to be invalidated, discarding up to a Cache Writeback
331	 * Granule (CWG) of data from the cache. Keep the section that
332	 * requires this type of maintenance to be in its own Cache Writeback
333	 * Granule (CWG) area so the cache maintenance operations don't
334	 * interfere with adjacent data.
335	 */
336	.mmuoff.data.write : ALIGN(SZ_2K) {
337		__mmuoff_data_start = .;
338		*(.mmuoff.data.write)
339	}
340	. = ALIGN(SZ_2K);
341	.mmuoff.data.read : {
342		*(.mmuoff.data.read)
343		__mmuoff_data_end = .;
344	}
345
346	PECOFF_EDATA_PADDING
347	__pecoff_data_rawsize = ABSOLUTE(. - __initdata_begin);
348	_edata = .;
349
350	/* start of zero-init region */
351	BSS_SECTION(SBSS_ALIGN, 0, 0)
352	__pi___bss_start = __bss_start;
353
354	. = ALIGN(PAGE_SIZE);
355	__pi_init_pg_dir = .;
356	. += INIT_DIR_SIZE;
357	__pi_init_pg_end = .;
358	/* end of zero-init region */
359
360	. += SZ_4K;		/* stack for the early C runtime */
361	early_init_stack = .;
362
363	. = ALIGN(SEGMENT_ALIGN);
364	__pecoff_data_size = ABSOLUTE(. - __initdata_begin);
365	_end = .;
366	__pi__end = .;
367
368	STABS_DEBUG
369	DWARF_DEBUG
370	MODINFO
371	ELF_DETAILS
372
373	HEAD_SYMBOLS
374
375	/*
376	 * Sections that should stay zero sized, which is safer to
377	 * explicitly check instead of blindly discarding.
378	 */
379	.plt : {
380		*(.plt) *(.plt.*) *(.iplt) *(.igot .igot.plt)
381	}
382	ASSERT(SIZEOF(.plt) == 0, "Unexpected run-time procedure linkages detected!")
383}
384
385#include "image-vars.h"
386
387/*
388 * The HYP init code and ID map text can't be longer than a page each. The
389 * former is page-aligned, but the latter may not be with 16K or 64K pages, so
390 * it should also not cross a page boundary.
391 */
392ASSERT(__hyp_idmap_text_end - __hyp_idmap_text_start <= PAGE_SIZE,
393	"HYP init code too big")
394ASSERT(__idmap_text_end - (__idmap_text_start & ~(SZ_4K - 1)) <= SZ_4K,
395	"ID map text too big or misaligned")
396#ifdef CONFIG_HIBERNATION
397ASSERT(__hibernate_exit_text_end - __hibernate_exit_text_start <= SZ_4K,
398       "Hibernate exit text is bigger than 4 KiB")
399ASSERT(__hibernate_exit_text_start == swsusp_arch_suspend_exit,
400       "Hibernate exit text does not start with swsusp_arch_suspend_exit")
401#endif
402#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
403ASSERT((__entry_tramp_text_end - __entry_tramp_text_start) <= 3*PAGE_SIZE,
404	"Entry trampoline text too big")
405#endif
406#ifdef CONFIG_KVM
407ASSERT(__hyp_bss_start == __bss_start, "HYP and Host BSS are misaligned")
408#endif
409/*
410 * If padding is applied before .head.text, virt<->phys conversions will fail.
411 */
412ASSERT(_text == KIMAGE_VADDR, "HEAD is misaligned")
413
414ASSERT(swapper_pg_dir - reserved_pg_dir == RESERVED_SWAPPER_OFFSET,
415       "RESERVED_SWAPPER_OFFSET is wrong!")
416
417#ifdef CONFIG_UNMAP_KERNEL_AT_EL0
418ASSERT(swapper_pg_dir - tramp_pg_dir == TRAMP_SWAPPER_OFFSET,
419       "TRAMP_SWAPPER_OFFSET is wrong!")
420#endif
421
422#ifdef CONFIG_KEXEC_CORE
423/* kexec relocation code should fit into one KEXEC_CONTROL_PAGE_SIZE */
424ASSERT(__relocate_new_kernel_end - __relocate_new_kernel_start <= SZ_4K,
425       "kexec relocation code is bigger than 4 KiB")
426ASSERT(KEXEC_CONTROL_PAGE_SIZE >= SZ_4K, "KEXEC_CONTROL_PAGE_SIZE is broken")
427ASSERT(__relocate_new_kernel_start == arm64_relocate_new_kernel,
428       "kexec control page does not start with arm64_relocate_new_kernel")
429#endif
430