1/* SPDX-License-Identifier: GPL-2.0 */ 2#define BSS_FIRST_SECTIONS *(.bss.prominit) 3#define EMITS_PT_NOTE 4#define RO_EXCEPTION_TABLE_ALIGN 0 5#define RUNTIME_DISCARD_EXIT 6 7#define SOFT_MASK_TABLE(align) \ 8 . = ALIGN(align); \ 9 __soft_mask_table : AT(ADDR(__soft_mask_table) - LOAD_OFFSET) { \ 10 __start___soft_mask_table = .; \ 11 KEEP(*(__soft_mask_table)) \ 12 __stop___soft_mask_table = .; \ 13 } 14 15#define RESTART_TABLE(align) \ 16 . = ALIGN(align); \ 17 __restart_table : AT(ADDR(__restart_table) - LOAD_OFFSET) { \ 18 __start___restart_table = .; \ 19 KEEP(*(__restart_table)) \ 20 __stop___restart_table = .; \ 21 } 22 23#include <asm/page.h> 24#include <asm-generic/vmlinux.lds.h> 25#include <asm/cache.h> 26#include <asm/thread_info.h> 27 28#define STRICT_ALIGN_SIZE (1 << CONFIG_DATA_SHIFT) 29 30#if STRICT_ALIGN_SIZE < PAGE_SIZE 31#error "CONFIG_DATA_SHIFT must be >= PAGE_SHIFT" 32#endif 33 34ENTRY(_stext) 35 36PHDRS { 37 text PT_LOAD FLAGS(7); /* RWX */ 38 note PT_NOTE FLAGS(0); 39} 40 41#ifdef CONFIG_PPC64 42OUTPUT_ARCH(powerpc:common64) 43jiffies = jiffies_64; 44#else 45OUTPUT_ARCH(powerpc:common) 46jiffies = jiffies_64 + 4; 47#endif 48SECTIONS 49{ 50 . = KERNELBASE; 51 52/* 53 * Text, read only data and other permanent read-only sections 54 */ 55 56 _text = .; 57 _stext = .; 58 59 /* 60 * Head text. 61 * This needs to be in its own output section to avoid ld placing 62 * branch trampoline stubs randomly throughout the fixed sections, 63 * which it will do (even if the branch comes from another section) 64 * in order to optimize stub generation. 65 */ 66 .head.text : AT(ADDR(.head.text) - LOAD_OFFSET) { 67#ifdef CONFIG_PPC64 68 KEEP(*(.head.text.first_256B)); 69#ifdef CONFIG_PPC_BOOK3E_64 70#else 71 KEEP(*(.head.text.real_vectors)); 72 *(.head.text.real_trampolines); 73 KEEP(*(.head.text.virt_vectors)); 74 *(.head.text.virt_trampolines); 75# if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) 76 KEEP(*(.head.data.fwnmi_page)); 77# endif 78#endif 79#else /* !CONFIG_PPC64 */ 80 HEAD_TEXT 81#endif 82 } :text 83 84 __head_end = .; 85 86#ifdef CONFIG_PPC64 87 /* 88 * ALIGN(0) overrides the default output section alignment because 89 * this needs to start right after .head.text in order for fixed 90 * section placement to work. 91 */ 92 .text ALIGN(0) : AT(ADDR(.text) - LOAD_OFFSET) { 93#ifdef CONFIG_LD_HEAD_STUB_CATCH 94 KEEP(*(.linker_stub_catch)); 95 . = . ; 96#endif 97 98#else 99 .text : AT(ADDR(.text) - LOAD_OFFSET) { 100 ALIGN_FUNCTION(); 101#endif 102 /* careful! __ftr_alt_* sections need to be close to .text */ 103 *(.text.hot .text.hot.* TEXT_MAIN .text.fixup .text.unlikely .text.unlikely.* .fixup __ftr_alt_* .ref.text); 104 *(.tramp.ftrace.text); 105 NOINSTR_TEXT 106 SCHED_TEXT 107 LOCK_TEXT 108 KPROBES_TEXT 109 IRQENTRY_TEXT 110 SOFTIRQENTRY_TEXT 111 /* 112 * -Os builds call FP save/restore functions. The powerpc64 113 * linker generates those on demand in the .sfpr section. 114 * .sfpr gets placed at the beginning of a group of input 115 * sections, which can break start-of-text offset if it is 116 * included with the main text sections, so put it by itself. 117 */ 118 *(.sfpr); 119 *(.text.asan.* .text.tsan.*) 120 } :text 121 122 . = ALIGN(PAGE_SIZE); 123 _etext = .; 124 125 /* Read-only data */ 126 RO_DATA(PAGE_SIZE) 127 128#ifdef CONFIG_PPC32 129 .sdata2 : AT(ADDR(.sdata2) - LOAD_OFFSET) { 130 *(.sdata2) 131 } 132#endif 133 134 .data.rel.ro : AT(ADDR(.data.rel.ro) - LOAD_OFFSET) { 135 *(.data.rel.ro .data.rel.ro.*) 136 } 137 138 .branch_lt : AT(ADDR(.branch_lt) - LOAD_OFFSET) { 139 *(.branch_lt) 140 } 141 142#ifdef CONFIG_PPC32 143 .got1 : AT(ADDR(.got1) - LOAD_OFFSET) { 144 *(.got1) 145 } 146 .got2 : AT(ADDR(.got2) - LOAD_OFFSET) { 147 __got2_start = .; 148 *(.got2) 149 __got2_end = .; 150 } 151 .got : AT(ADDR(.got) - LOAD_OFFSET) { 152 *(.got) 153 *(.got.plt) 154 } 155 .plt : AT(ADDR(.plt) - LOAD_OFFSET) { 156 /* XXX: is .plt (and .got.plt) required? */ 157 *(.plt) 158 } 159 160#else /* CONFIG_PPC32 */ 161#ifndef CONFIG_PPC_KERNEL_PCREL 162 .toc1 : AT(ADDR(.toc1) - LOAD_OFFSET) { 163 *(.toc1) 164 } 165#endif 166 167 .got : AT(ADDR(.got) - LOAD_OFFSET) ALIGN(256) { 168#ifdef CONFIG_PPC_KERNEL_PCREL 169 *(.got) 170#else 171 *(.got .toc) 172#endif 173 } 174 175 SOFT_MASK_TABLE(8) 176 RESTART_TABLE(8) 177 178#ifdef CONFIG_PPC64_ELF_ABI_V1 179 .opd : AT(ADDR(.opd) - LOAD_OFFSET) { 180 __start_opd = .; 181 KEEP(*(.opd)) 182 __end_opd = .; 183 } 184#endif 185 186 . = ALIGN(8); 187 __stf_entry_barrier_fixup : AT(ADDR(__stf_entry_barrier_fixup) - LOAD_OFFSET) { 188 __start___stf_entry_barrier_fixup = .; 189 *(__stf_entry_barrier_fixup) 190 __stop___stf_entry_barrier_fixup = .; 191 } 192 193 . = ALIGN(8); 194 __uaccess_flush_fixup : AT(ADDR(__uaccess_flush_fixup) - LOAD_OFFSET) { 195 __start___uaccess_flush_fixup = .; 196 *(__uaccess_flush_fixup) 197 __stop___uaccess_flush_fixup = .; 198 } 199 200 . = ALIGN(8); 201 __entry_flush_fixup : AT(ADDR(__entry_flush_fixup) - LOAD_OFFSET) { 202 __start___entry_flush_fixup = .; 203 *(__entry_flush_fixup) 204 __stop___entry_flush_fixup = .; 205 } 206 207 . = ALIGN(8); 208 __scv_entry_flush_fixup : AT(ADDR(__scv_entry_flush_fixup) - LOAD_OFFSET) { 209 __start___scv_entry_flush_fixup = .; 210 *(__scv_entry_flush_fixup) 211 __stop___scv_entry_flush_fixup = .; 212 } 213 214 . = ALIGN(8); 215 __stf_exit_barrier_fixup : AT(ADDR(__stf_exit_barrier_fixup) - LOAD_OFFSET) { 216 __start___stf_exit_barrier_fixup = .; 217 *(__stf_exit_barrier_fixup) 218 __stop___stf_exit_barrier_fixup = .; 219 } 220 221 . = ALIGN(8); 222 __rfi_flush_fixup : AT(ADDR(__rfi_flush_fixup) - LOAD_OFFSET) { 223 __start___rfi_flush_fixup = .; 224 *(__rfi_flush_fixup) 225 __stop___rfi_flush_fixup = .; 226 } 227#endif /* CONFIG_PPC32 */ 228 229#ifdef CONFIG_PPC_BARRIER_NOSPEC 230 . = ALIGN(8); 231 __spec_barrier_fixup : AT(ADDR(__spec_barrier_fixup) - LOAD_OFFSET) { 232 __start___barrier_nospec_fixup = .; 233 *(__barrier_nospec_fixup) 234 __stop___barrier_nospec_fixup = .; 235 } 236#endif /* CONFIG_PPC_BARRIER_NOSPEC */ 237 238#ifdef CONFIG_PPC_E500 239 . = ALIGN(8); 240 __spec_btb_flush_fixup : AT(ADDR(__spec_btb_flush_fixup) - LOAD_OFFSET) { 241 __start__btb_flush_fixup = .; 242 *(__btb_flush_fixup) 243 __stop__btb_flush_fixup = .; 244 } 245#endif 246 247 /* 248 * Various code relies on __init_begin being at the strict RWX boundary. 249 */ 250 . = ALIGN(STRICT_ALIGN_SIZE); 251 __srwx_boundary = .; 252 __end_rodata = .; 253 __init_begin = .; 254 255/* 256 * Init sections discarded at runtime 257 */ 258 .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) { 259 _sinittext = .; 260 INIT_TEXT 261 *(.tramp.ftrace.init); 262 /* 263 *.init.text might be RO so we must ensure this section ends on 264 * a page boundary. 265 */ 266 . = ALIGN(PAGE_SIZE); 267 _einittext = .; 268 } :text 269 270 /* .exit.text is discarded at runtime, not link time, 271 * to deal with references from __bug_table 272 */ 273 .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { 274 __exittext_begin = .; 275 EXIT_TEXT 276 __exittext_end = .; 277 } 278 279 . = ALIGN(PAGE_SIZE); 280 281 INIT_DATA_SECTION(16) 282 283 . = ALIGN(8); 284 __ftr_fixup : AT(ADDR(__ftr_fixup) - LOAD_OFFSET) { 285 __start___ftr_fixup = .; 286 KEEP(*(__ftr_fixup)) 287 __stop___ftr_fixup = .; 288 } 289 . = ALIGN(8); 290 __mmu_ftr_fixup : AT(ADDR(__mmu_ftr_fixup) - LOAD_OFFSET) { 291 __start___mmu_ftr_fixup = .; 292 KEEP(*(__mmu_ftr_fixup)) 293 __stop___mmu_ftr_fixup = .; 294 } 295 . = ALIGN(8); 296 __lwsync_fixup : AT(ADDR(__lwsync_fixup) - LOAD_OFFSET) { 297 __start___lwsync_fixup = .; 298 KEEP(*(__lwsync_fixup)) 299 __stop___lwsync_fixup = .; 300 } 301#ifdef CONFIG_PPC64 302 . = ALIGN(8); 303 __fw_ftr_fixup : AT(ADDR(__fw_ftr_fixup) - LOAD_OFFSET) { 304 __start___fw_ftr_fixup = .; 305 KEEP(*(__fw_ftr_fixup)) 306 __stop___fw_ftr_fixup = .; 307 } 308#endif 309 310 PERCPU_SECTION(L1_CACHE_BYTES) 311 312 . = ALIGN(8); 313 .machine.desc : AT(ADDR(.machine.desc) - LOAD_OFFSET) { 314 __machine_desc_start = . ; 315 KEEP(*(.machine.desc)) 316 __machine_desc_end = . ; 317 } 318#ifdef CONFIG_RELOCATABLE 319 . = ALIGN(8); 320 .dynsym : AT(ADDR(.dynsym) - LOAD_OFFSET) 321 { 322 __dynamic_symtab = .; 323 *(.dynsym) 324 } 325 .dynstr : AT(ADDR(.dynstr) - LOAD_OFFSET) { *(.dynstr) } 326 .dynamic : AT(ADDR(.dynamic) - LOAD_OFFSET) 327 { 328 __dynamic_start = .; 329 *(.dynamic) 330 } 331 .hash : AT(ADDR(.hash) - LOAD_OFFSET) { *(.hash) } 332 .gnu.hash : AT(ADDR(.gnu.hash) - LOAD_OFFSET) { *(.gnu.hash) } 333 .interp : AT(ADDR(.interp) - LOAD_OFFSET) { *(.interp) } 334 .rela.dyn : AT(ADDR(.rela.dyn) - LOAD_OFFSET) 335 { 336 __rela_dyn_start = .; 337 *(.rela*) 338 } 339#endif 340 /* .exit.data is discarded at runtime, not link time, 341 * to deal with references from .exit.text 342 */ 343 .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { 344 EXIT_DATA 345 } 346 347 /* freed after init ends here */ 348 . = ALIGN(PAGE_SIZE); 349 __init_end = .; 350 351/* 352 * And now the various read/write data 353 */ 354 355 . = ALIGN(PAGE_SIZE); 356 _sdata = .; 357 358 .data : AT(ADDR(.data) - LOAD_OFFSET) { 359 DATA_DATA 360 *(.data.rel*) 361#ifdef CONFIG_PPC32 362 *(SDATA_MAIN) 363#endif 364 } 365 366 /* The initial task and kernel stack */ 367 INIT_TASK_DATA_SECTION(THREAD_ALIGN) 368 369 .data..page_aligned : AT(ADDR(.data..page_aligned) - LOAD_OFFSET) { 370 PAGE_ALIGNED_DATA(PAGE_SIZE) 371 } 372 373 .data..cacheline_aligned : AT(ADDR(.data..cacheline_aligned) - LOAD_OFFSET) { 374 CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES) 375 } 376 377 .data..read_mostly : AT(ADDR(.data..read_mostly) - LOAD_OFFSET) { 378 READ_MOSTLY_DATA(L1_CACHE_BYTES) 379 } 380 381 . = ALIGN(PAGE_SIZE); 382 .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { 383 NOSAVE_DATA 384 } 385 386 BUG_TABLE 387 388 . = ALIGN(PAGE_SIZE); 389 _edata = .; 390 391/* 392 * And finally the bss 393 */ 394 395 BSS_SECTION(0, 0, 0) 396 397 . = ALIGN(PAGE_SIZE); 398 _end = . ; 399 400 DWARF_DEBUG 401 ELF_DETAILS 402 403 DISCARDS 404 /DISCARD/ : { 405 *(*.EMB.apuinfo) 406 *(.glink .iplt .plt) 407 *(.gnu.version*) 408 *(.gnu.attributes) 409 *(.eh_frame) 410#ifndef CONFIG_RELOCATABLE 411 *(.rela*) 412#endif 413 } 414} 415