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#define RO_EXCEPTION_TABLE_ALIGN 8 9#define RUNTIME_DISCARD_EXIT 10 11#include <asm-generic/vmlinux.lds.h> 12#include <asm/cache.h> 13#include <asm/hyp_image.h> 14#include <asm/kernel-pgtable.h> 15#include <asm/memory.h> 16#include <asm/page.h> 17 18#include "image.h" 19 20OUTPUT_ARCH(aarch64) 21ENTRY(_text) 22 23jiffies = jiffies_64; 24 25 26#ifdef CONFIG_KVM 27#define HYPERVISOR_EXTABLE \ 28 . = ALIGN(SZ_8); \ 29 __start___kvm_ex_table = .; \ 30 *(__kvm_ex_table) \ 31 __stop___kvm_ex_table = .; 32 33#define HYPERVISOR_DATA_SECTIONS \ 34 HYP_SECTION_NAME(.rodata) : { \ 35 __hyp_rodata_start = .; \ 36 *(HYP_SECTION_NAME(.data..ro_after_init)) \ 37 *(HYP_SECTION_NAME(.rodata)) \ 38 __hyp_rodata_end = .; \ 39 } 40 41#define HYPERVISOR_PERCPU_SECTION \ 42 . = ALIGN(PAGE_SIZE); \ 43 HYP_SECTION_NAME(.data..percpu) : { \ 44 *(HYP_SECTION_NAME(.data..percpu)) \ 45 } 46 47#define HYPERVISOR_RELOC_SECTION \ 48 .hyp.reloc : ALIGN(4) { \ 49 __hyp_reloc_begin = .; \ 50 *(.hyp.reloc) \ 51 __hyp_reloc_end = .; \ 52 } 53 54#else /* CONFIG_KVM */ 55#define HYPERVISOR_EXTABLE 56#define HYPERVISOR_DATA_SECTIONS 57#define HYPERVISOR_PERCPU_SECTION 58#define HYPERVISOR_RELOC_SECTION 59#endif 60 61#define HYPERVISOR_TEXT \ 62 /* \ 63 * Align to 4 KB so that \ 64 * a) the HYP vector table is at its minimum \ 65 * alignment of 2048 bytes \ 66 * b) the HYP init code will not cross a page \ 67 * boundary if its size does not exceed \ 68 * 4 KB (see related ASSERT() below) \ 69 */ \ 70 . = ALIGN(SZ_4K); \ 71 __hyp_idmap_text_start = .; \ 72 *(.hyp.idmap.text) \ 73 __hyp_idmap_text_end = .; \ 74 __hyp_text_start = .; \ 75 *(.hyp.text) \ 76 HYPERVISOR_EXTABLE \ 77 __hyp_text_end = .; 78 79#define IDMAP_TEXT \ 80 . = ALIGN(SZ_4K); \ 81 __idmap_text_start = .; \ 82 *(.idmap.text) \ 83 __idmap_text_end = .; 84 85#ifdef CONFIG_HIBERNATION 86#define HIBERNATE_TEXT \ 87 . = ALIGN(SZ_4K); \ 88 __hibernate_exit_text_start = .; \ 89 *(.hibernate_exit.text) \ 90 __hibernate_exit_text_end = .; 91#else 92#define HIBERNATE_TEXT 93#endif 94 95#ifdef CONFIG_UNMAP_KERNEL_AT_EL0 96#define TRAMP_TEXT \ 97 . = ALIGN(PAGE_SIZE); \ 98 __entry_tramp_text_start = .; \ 99 *(.entry.tramp.text) \ 100 . = ALIGN(PAGE_SIZE); \ 101 __entry_tramp_text_end = .; 102#else 103#define TRAMP_TEXT 104#endif 105 106/* 107 * The size of the PE/COFF section that covers the kernel image, which 108 * runs from _stext to _edata, must be a round multiple of the PE/COFF 109 * FileAlignment, which we set to its minimum value of 0x200. '_stext' 110 * itself is 4 KB aligned, so padding out _edata to a 0x200 aligned 111 * boundary should be sufficient. 112 */ 113PECOFF_FILE_ALIGNMENT = 0x200; 114 115#ifdef CONFIG_EFI 116#define PECOFF_EDATA_PADDING \ 117 .pecoff_edata_padding : { BYTE(0); . = ALIGN(PECOFF_FILE_ALIGNMENT); } 118#else 119#define PECOFF_EDATA_PADDING 120#endif 121 122SECTIONS 123{ 124 /* 125 * XXX: The linker does not define how output sections are 126 * assigned to input sections when there are multiple statements 127 * matching the same input section name. There is no documented 128 * order of matching. 129 */ 130 DISCARDS 131 /DISCARD/ : { 132 *(.interp .dynamic) 133 *(.dynsym .dynstr .hash .gnu.hash) 134 } 135 136 . = KIMAGE_VADDR; 137 138 .head.text : { 139 _text = .; 140 HEAD_TEXT 141 } 142 .text : ALIGN(SEGMENT_ALIGN) { /* Real text segment */ 143 _stext = .; /* Text and read-only data */ 144 IRQENTRY_TEXT 145 SOFTIRQENTRY_TEXT 146 ENTRY_TEXT 147 TEXT_TEXT 148 SCHED_TEXT 149 CPUIDLE_TEXT 150 LOCK_TEXT 151 KPROBES_TEXT 152 HYPERVISOR_TEXT 153 IDMAP_TEXT 154 HIBERNATE_TEXT 155 TRAMP_TEXT 156 *(.fixup) 157 *(.gnu.warning) 158 . = ALIGN(16); 159 *(.got) /* Global offset table */ 160 } 161 162 /* 163 * Make sure that the .got.plt is either completely empty or it 164 * contains only the lazy dispatch entries. 165 */ 166 .got.plt : { *(.got.plt) } 167 ASSERT(SIZEOF(.got.plt) == 0 || SIZEOF(.got.plt) == 0x18, 168 "Unexpected GOT/PLT entries detected!") 169 170 . = ALIGN(SEGMENT_ALIGN); 171 _etext = .; /* End of text section */ 172 173 /* everything from this point to __init_begin will be marked RO NX */ 174 RO_DATA(PAGE_SIZE) 175 176 idmap_pg_dir = .; 177 . += IDMAP_DIR_SIZE; 178 idmap_pg_end = .; 179 180#ifdef CONFIG_UNMAP_KERNEL_AT_EL0 181 tramp_pg_dir = .; 182 . += PAGE_SIZE; 183#endif 184 185 reserved_pg_dir = .; 186 . += PAGE_SIZE; 187 188 swapper_pg_dir = .; 189 . += PAGE_SIZE; 190 191 . = ALIGN(SEGMENT_ALIGN); 192 __init_begin = .; 193 __inittext_begin = .; 194 195 INIT_TEXT_SECTION(8) 196 197 __exittext_begin = .; 198 .exit.text : { 199 EXIT_TEXT 200 } 201 __exittext_end = .; 202 203 . = ALIGN(4); 204 .altinstructions : { 205 __alt_instructions = .; 206 *(.altinstructions) 207 __alt_instructions_end = .; 208 } 209 210 . = ALIGN(SEGMENT_ALIGN); 211 __inittext_end = .; 212 __initdata_begin = .; 213 214 .init.data : { 215 INIT_DATA 216 INIT_SETUP(16) 217 INIT_CALLS 218 CON_INITCALL 219 INIT_RAM_FS 220 *(.init.altinstructions .init.bss) /* from the EFI stub */ 221 } 222 .exit.data : { 223 EXIT_DATA 224 } 225 226 PERCPU_SECTION(L1_CACHE_BYTES) 227 HYPERVISOR_PERCPU_SECTION 228 229 HYPERVISOR_RELOC_SECTION 230 231 .rela.dyn : ALIGN(8) { 232 *(.rela .rela*) 233 } 234 235 __rela_offset = ABSOLUTE(ADDR(.rela.dyn) - KIMAGE_VADDR); 236 __rela_size = SIZEOF(.rela.dyn); 237 238#ifdef CONFIG_RELR 239 .relr.dyn : ALIGN(8) { 240 *(.relr.dyn) 241 } 242 243 __relr_offset = ABSOLUTE(ADDR(.relr.dyn) - KIMAGE_VADDR); 244 __relr_size = SIZEOF(.relr.dyn); 245#endif 246 247 . = ALIGN(SEGMENT_ALIGN); 248 __initdata_end = .; 249 __init_end = .; 250 251 _data = .; 252 _sdata = .; 253 RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_ALIGN) 254 255 HYPERVISOR_DATA_SECTIONS 256 257 /* 258 * Data written with the MMU off but read with the MMU on requires 259 * cache lines to be invalidated, discarding up to a Cache Writeback 260 * Granule (CWG) of data from the cache. Keep the section that 261 * requires this type of maintenance to be in its own Cache Writeback 262 * Granule (CWG) area so the cache maintenance operations don't 263 * interfere with adjacent data. 264 */ 265 .mmuoff.data.write : ALIGN(SZ_2K) { 266 __mmuoff_data_start = .; 267 *(.mmuoff.data.write) 268 } 269 . = ALIGN(SZ_2K); 270 .mmuoff.data.read : { 271 *(.mmuoff.data.read) 272 __mmuoff_data_end = .; 273 } 274 275 PECOFF_EDATA_PADDING 276 __pecoff_data_rawsize = ABSOLUTE(. - __initdata_begin); 277 _edata = .; 278 279 BSS_SECTION(0, 0, 0) 280 281 . = ALIGN(PAGE_SIZE); 282 init_pg_dir = .; 283 . += INIT_DIR_SIZE; 284 init_pg_end = .; 285 286 . = ALIGN(SEGMENT_ALIGN); 287 __pecoff_data_size = ABSOLUTE(. - __initdata_begin); 288 _end = .; 289 290 STABS_DEBUG 291 DWARF_DEBUG 292 ELF_DETAILS 293 294 HEAD_SYMBOLS 295 296 /* 297 * Sections that should stay zero sized, which is safer to 298 * explicitly check instead of blindly discarding. 299 */ 300 .plt : { 301 *(.plt) *(.plt.*) *(.iplt) *(.igot .igot.plt) 302 } 303 ASSERT(SIZEOF(.plt) == 0, "Unexpected run-time procedure linkages detected!") 304 305 .data.rel.ro : { *(.data.rel.ro) } 306 ASSERT(SIZEOF(.data.rel.ro) == 0, "Unexpected RELRO detected!") 307} 308 309#include "image-vars.h" 310 311/* 312 * The HYP init code and ID map text can't be longer than a page each, 313 * and should not cross a page boundary. 314 */ 315ASSERT(__hyp_idmap_text_end - (__hyp_idmap_text_start & ~(SZ_4K - 1)) <= SZ_4K, 316 "HYP init code too big or misaligned") 317ASSERT(__idmap_text_end - (__idmap_text_start & ~(SZ_4K - 1)) <= SZ_4K, 318 "ID map text too big or misaligned") 319#ifdef CONFIG_HIBERNATION 320ASSERT(__hibernate_exit_text_end - (__hibernate_exit_text_start & ~(SZ_4K - 1)) 321 <= SZ_4K, "Hibernate exit text too big or misaligned") 322#endif 323#ifdef CONFIG_UNMAP_KERNEL_AT_EL0 324ASSERT((__entry_tramp_text_end - __entry_tramp_text_start) == PAGE_SIZE, 325 "Entry trampoline text too big") 326#endif 327/* 328 * If padding is applied before .head.text, virt<->phys conversions will fail. 329 */ 330ASSERT(_text == KIMAGE_VADDR, "HEAD is misaligned") 331 332ASSERT(swapper_pg_dir - reserved_pg_dir == RESERVED_SWAPPER_OFFSET, 333 "RESERVED_SWAPPER_OFFSET is wrong!") 334 335#ifdef CONFIG_UNMAP_KERNEL_AT_EL0 336ASSERT(swapper_pg_dir - tramp_pg_dir == TRAMP_SWAPPER_OFFSET, 337 "TRAMP_SWAPPER_OFFSET is wrong!") 338#endif 339