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