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