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_64 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 LOCK_TEXT 116 KPROBES_TEXT 117 IRQENTRY_TEXT 118 SOFTIRQENTRY_TEXT 119 /* 120 * -Os builds call FP save/restore functions. The powerpc64 121 * linker generates those on demand in the .sfpr section. 122 * .sfpr gets placed at the beginning of a group of input 123 * sections, which can break start-of-text offset if it is 124 * included with the main text sections, so put it by itself. 125 */ 126 *(.sfpr); 127 *(.text.asan.* .text.tsan.*) 128 MEM_KEEP(init.text) 129 MEM_KEEP(exit.text) 130 } :text 131 132 . = ALIGN(PAGE_SIZE); 133 _etext = .; 134 PROVIDE32 (etext = .); 135 136 /* Read-only data */ 137 RO_DATA(PAGE_SIZE) 138 139#ifdef CONFIG_PPC32 140 .sdata2 : AT(ADDR(.sdata2) - LOAD_OFFSET) { 141 *(.sdata2) 142 } 143#endif 144 145 .data.rel.ro : AT(ADDR(.data.rel.ro) - LOAD_OFFSET) { 146 *(.data.rel.ro .data.rel.ro.*) 147 } 148 149 .branch_lt : AT(ADDR(.branch_lt) - LOAD_OFFSET) { 150 *(.branch_lt) 151 } 152 153#ifdef CONFIG_PPC32 154 .got1 : AT(ADDR(.got1) - LOAD_OFFSET) { 155 *(.got1) 156 } 157 .got2 : AT(ADDR(.got2) - LOAD_OFFSET) { 158 __got2_start = .; 159 *(.got2) 160 __got2_end = .; 161 } 162 .got : AT(ADDR(.got) - LOAD_OFFSET) { 163 *(.got) 164 *(.got.plt) 165 } 166 .plt : AT(ADDR(.plt) - LOAD_OFFSET) { 167 /* XXX: is .plt (and .got.plt) required? */ 168 *(.plt) 169 } 170 171#else /* CONFIG_PPC32 */ 172#ifndef CONFIG_PPC_KERNEL_PCREL 173 .toc1 : AT(ADDR(.toc1) - LOAD_OFFSET) { 174 *(.toc1) 175 } 176#endif 177 178 .got : AT(ADDR(.got) - LOAD_OFFSET) ALIGN(256) { 179#ifdef CONFIG_PPC_KERNEL_PCREL 180 *(.got) 181#else 182 *(.got .toc) 183#endif 184 } 185 186 SOFT_MASK_TABLE(8) 187 RESTART_TABLE(8) 188 189#ifdef CONFIG_PPC64_ELF_ABI_V1 190 .opd : AT(ADDR(.opd) - LOAD_OFFSET) { 191 __start_opd = .; 192 KEEP(*(.opd)) 193 __end_opd = .; 194 } 195#endif 196 197 . = ALIGN(8); 198 __stf_entry_barrier_fixup : AT(ADDR(__stf_entry_barrier_fixup) - LOAD_OFFSET) { 199 __start___stf_entry_barrier_fixup = .; 200 *(__stf_entry_barrier_fixup) 201 __stop___stf_entry_barrier_fixup = .; 202 } 203 204 . = ALIGN(8); 205 __uaccess_flush_fixup : AT(ADDR(__uaccess_flush_fixup) - LOAD_OFFSET) { 206 __start___uaccess_flush_fixup = .; 207 *(__uaccess_flush_fixup) 208 __stop___uaccess_flush_fixup = .; 209 } 210 211 . = ALIGN(8); 212 __entry_flush_fixup : AT(ADDR(__entry_flush_fixup) - LOAD_OFFSET) { 213 __start___entry_flush_fixup = .; 214 *(__entry_flush_fixup) 215 __stop___entry_flush_fixup = .; 216 } 217 218 . = ALIGN(8); 219 __scv_entry_flush_fixup : AT(ADDR(__scv_entry_flush_fixup) - LOAD_OFFSET) { 220 __start___scv_entry_flush_fixup = .; 221 *(__scv_entry_flush_fixup) 222 __stop___scv_entry_flush_fixup = .; 223 } 224 225 . = ALIGN(8); 226 __stf_exit_barrier_fixup : AT(ADDR(__stf_exit_barrier_fixup) - LOAD_OFFSET) { 227 __start___stf_exit_barrier_fixup = .; 228 *(__stf_exit_barrier_fixup) 229 __stop___stf_exit_barrier_fixup = .; 230 } 231 232 . = ALIGN(8); 233 __rfi_flush_fixup : AT(ADDR(__rfi_flush_fixup) - LOAD_OFFSET) { 234 __start___rfi_flush_fixup = .; 235 *(__rfi_flush_fixup) 236 __stop___rfi_flush_fixup = .; 237 } 238#endif /* CONFIG_PPC32 */ 239 240#ifdef CONFIG_PPC_BARRIER_NOSPEC 241 . = ALIGN(8); 242 __spec_barrier_fixup : AT(ADDR(__spec_barrier_fixup) - LOAD_OFFSET) { 243 __start___barrier_nospec_fixup = .; 244 *(__barrier_nospec_fixup) 245 __stop___barrier_nospec_fixup = .; 246 } 247#endif /* CONFIG_PPC_BARRIER_NOSPEC */ 248 249#ifdef CONFIG_PPC_E500 250 . = ALIGN(8); 251 __spec_btb_flush_fixup : AT(ADDR(__spec_btb_flush_fixup) - LOAD_OFFSET) { 252 __start__btb_flush_fixup = .; 253 *(__btb_flush_fixup) 254 __stop__btb_flush_fixup = .; 255 } 256#endif 257 258 /* 259 * Various code relies on __init_begin being at the strict RWX boundary. 260 */ 261 . = ALIGN(STRICT_ALIGN_SIZE); 262 __srwx_boundary = .; 263 __end_rodata = .; 264 __init_begin = .; 265 266/* 267 * Init sections discarded at runtime 268 */ 269 .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) { 270 _sinittext = .; 271 INIT_TEXT 272 273 /* 274 *.init.text might be RO so we must ensure this section ends on 275 * a page boundary. 276 */ 277 . = ALIGN(PAGE_SIZE); 278 _einittext = .; 279#ifdef CONFIG_PPC64 280 *(.tramp.ftrace.init); 281#endif 282 } :text 283 284 /* .exit.text is discarded at runtime, not link time, 285 * to deal with references from __bug_table 286 */ 287 .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { 288 EXIT_TEXT 289 } 290 291 . = ALIGN(PAGE_SIZE); 292 293 INIT_DATA_SECTION(16) 294 295 . = ALIGN(8); 296 __ftr_fixup : AT(ADDR(__ftr_fixup) - LOAD_OFFSET) { 297 __start___ftr_fixup = .; 298 KEEP(*(__ftr_fixup)) 299 __stop___ftr_fixup = .; 300 } 301 . = ALIGN(8); 302 __mmu_ftr_fixup : AT(ADDR(__mmu_ftr_fixup) - LOAD_OFFSET) { 303 __start___mmu_ftr_fixup = .; 304 KEEP(*(__mmu_ftr_fixup)) 305 __stop___mmu_ftr_fixup = .; 306 } 307 . = ALIGN(8); 308 __lwsync_fixup : AT(ADDR(__lwsync_fixup) - LOAD_OFFSET) { 309 __start___lwsync_fixup = .; 310 KEEP(*(__lwsync_fixup)) 311 __stop___lwsync_fixup = .; 312 } 313#ifdef CONFIG_PPC64 314 . = ALIGN(8); 315 __fw_ftr_fixup : AT(ADDR(__fw_ftr_fixup) - LOAD_OFFSET) { 316 __start___fw_ftr_fixup = .; 317 KEEP(*(__fw_ftr_fixup)) 318 __stop___fw_ftr_fixup = .; 319 } 320#endif 321 322 PERCPU_SECTION(L1_CACHE_BYTES) 323 324 . = ALIGN(8); 325 .machine.desc : AT(ADDR(.machine.desc) - LOAD_OFFSET) { 326 __machine_desc_start = . ; 327 KEEP(*(.machine.desc)) 328 __machine_desc_end = . ; 329 } 330#ifdef CONFIG_RELOCATABLE 331 . = ALIGN(8); 332 .dynsym : AT(ADDR(.dynsym) - LOAD_OFFSET) 333 { 334 __dynamic_symtab = .; 335 *(.dynsym) 336 } 337 .dynstr : AT(ADDR(.dynstr) - LOAD_OFFSET) { *(.dynstr) } 338 .dynamic : AT(ADDR(.dynamic) - LOAD_OFFSET) 339 { 340 __dynamic_start = .; 341 *(.dynamic) 342 } 343 .hash : AT(ADDR(.hash) - LOAD_OFFSET) { *(.hash) } 344 .gnu.hash : AT(ADDR(.gnu.hash) - LOAD_OFFSET) { *(.gnu.hash) } 345 .interp : AT(ADDR(.interp) - LOAD_OFFSET) { *(.interp) } 346 .rela.dyn : AT(ADDR(.rela.dyn) - LOAD_OFFSET) 347 { 348 __rela_dyn_start = .; 349 *(.rela*) 350 } 351#endif 352 /* .exit.data is discarded at runtime, not link time, 353 * to deal with references from .exit.text 354 */ 355 .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { 356 EXIT_DATA 357 } 358 359 /* freed after init ends here */ 360 . = ALIGN(PAGE_SIZE); 361 __init_end = .; 362 363/* 364 * And now the various read/write data 365 */ 366 367 . = ALIGN(PAGE_SIZE); 368 _sdata = .; 369 370 .data : AT(ADDR(.data) - LOAD_OFFSET) { 371 DATA_DATA 372 *(.data.rel*) 373#ifdef CONFIG_PPC32 374 *(SDATA_MAIN) 375#endif 376 } 377 378 /* The initial task and kernel stack */ 379 INIT_TASK_DATA_SECTION(THREAD_ALIGN) 380 381 .data..page_aligned : AT(ADDR(.data..page_aligned) - LOAD_OFFSET) { 382 PAGE_ALIGNED_DATA(PAGE_SIZE) 383 } 384 385 .data..cacheline_aligned : AT(ADDR(.data..cacheline_aligned) - LOAD_OFFSET) { 386 CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES) 387 } 388 389 .data..read_mostly : AT(ADDR(.data..read_mostly) - LOAD_OFFSET) { 390 READ_MOSTLY_DATA(L1_CACHE_BYTES) 391 } 392 393 . = ALIGN(PAGE_SIZE); 394 .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { 395 NOSAVE_DATA 396 } 397 398 BUG_TABLE 399 400 . = ALIGN(PAGE_SIZE); 401 _edata = .; 402 PROVIDE32 (edata = .); 403 404/* 405 * And finally the bss 406 */ 407 408 BSS_SECTION(0, 0, 0) 409 410 . = ALIGN(PAGE_SIZE); 411 _end = . ; 412 PROVIDE32 (end = .); 413 414 DWARF_DEBUG 415 ELF_DETAILS 416 417 DISCARDS 418 /DISCARD/ : { 419 *(*.EMB.apuinfo) 420 *(.glink .iplt .plt) 421 *(.gnu.version*) 422 *(.gnu.attributes) 423 *(.eh_frame) 424#ifndef CONFIG_RELOCATABLE 425 *(.rela*) 426#endif 427 } 428} 429