| 1 | /* SPDX-License-Identifier: GPL-2.0 */
|
| 2 | /* ld script to make s390 Linux kernel
|
| 3 | * Written by Martin Schwidefsky (schwidefsky@de.ibm.com)
|
| 4 | */
|
| 5 |
|
| 6 | |
| 7 | |
| 8 | |
| 9 |
|
| 10 | /*
|
| 11 | * Put .bss..swapper_pg_dir as the first thing in .bss. This will
|
| 12 | * make sure it has 16k alignment.
|
| 13 | */
|
| 14 | |
| 15 | *(.bss..invalid_pg_dir)
|
| 16 |
|
| 17 | |
| 18 |
|
| 19 | /* Handle ro_after_init data on our own. */
|
| 20 | |
| 21 |
|
| 22 | |
| 23 |
|
| 24 | |
| 25 |
|
| 26 | |
| 27 | |
| 28 |
|
| 29 | OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390")
|
| 30 | OUTPUT_ARCH(s390:64-bit)
|
| 31 | ENTRY(startup_continue)
|
| 32 | jiffies = jiffies_64;
|
| 33 |
|
| 34 | PHDRS {
|
| 35 | text PT_LOAD FLAGS(5); /* R_E */
|
| 36 | data PT_LOAD FLAGS(7); /* RWE */
|
| 37 | note PT_NOTE FLAGS(0); /* ___ */
|
| 38 | }
|
| 39 |
|
| 40 | SECTIONS
|
| 41 | {
|
| 42 | . = TEXT_OFFSET;
|
| 43 | .text : {
|
| 44 | _stext = .; /* Start of text section */
|
| 45 | _text = .; /* Text and read-only data */
|
| 46 | HEAD_TEXT
|
| 47 | TEXT_TEXT
|
| 48 | SCHED_TEXT
|
| 49 | LOCK_TEXT
|
| 50 | KPROBES_TEXT
|
| 51 | IRQENTRY_TEXT
|
| 52 | SOFTIRQENTRY_TEXT
|
| 53 | FTRACE_HOTPATCH_TRAMPOLINES_TEXT
|
| 54 | *(.text..*_indirect_*)
|
| 55 | *(.gnu.warning)
|
| 56 | . = ALIGN(PAGE_SIZE);
|
| 57 | _etext = .; /* End of text section */
|
| 58 | } :text = 0x0700
|
| 59 |
|
| 60 | RO_DATA(PAGE_SIZE)
|
| 61 |
|
| 62 | . = ALIGN(PAGE_SIZE);
|
| 63 | _sdata = .; /* Start of data section */
|
| 64 |
|
| 65 | . = ALIGN(PAGE_SIZE);
|
| 66 | __start_ro_after_init = .;
|
| 67 | .data..ro_after_init : {
|
| 68 | *(.data..ro_after_init)
|
| 69 | JUMP_TABLE_DATA
|
| 70 | } :data
|
| 71 | . = ALIGN(PAGE_SIZE);
|
| 72 | __end_ro_after_init = .;
|
| 73 |
|
| 74 | . = ALIGN(8);
|
| 75 | .skey_region_table : {
|
| 76 | __skey_region_start = .;
|
| 77 | KEEP(*(.skey_region))
|
| 78 | __skey_region_end = .;
|
| 79 | }
|
| 80 |
|
| 81 | .data.rel.ro : {
|
| 82 | *(.data.rel.ro .data.rel.ro.*)
|
| 83 | }
|
| 84 | .got : {
|
| 85 | __got_start = .;
|
| 86 | *(.got)
|
| 87 | __got_end = .;
|
| 88 | }
|
| 89 |
|
| 90 | RW_DATA(0x100, PAGE_SIZE, THREAD_SIZE)
|
| 91 | .data.rel : {
|
| 92 | *(.data.rel*)
|
| 93 | }
|
| 94 | BOOT_DATA_PRESERVED
|
| 95 |
|
| 96 | . = ALIGN(8);
|
| 97 | .amode31.refs : {
|
| 98 | _start_amode31_refs = .;
|
| 99 | *(.amode31.refs)
|
| 100 | _end_amode31_refs = .;
|
| 101 | }
|
| 102 |
|
| 103 | . = ALIGN(PAGE_SIZE);
|
| 104 | _edata = .; /* End of data section */
|
| 105 |
|
| 106 | /* will be freed after init */
|
| 107 | . = ALIGN(PAGE_SIZE); /* Init code and data */
|
| 108 | __init_begin = .;
|
| 109 |
|
| 110 | . = ALIGN(PAGE_SIZE);
|
| 111 | .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
|
| 112 | _sinittext = .;
|
| 113 | INIT_TEXT
|
| 114 | . = ALIGN(PAGE_SIZE);
|
| 115 | _einittext = .;
|
| 116 | }
|
| 117 |
|
| 118 | /*
|
| 119 | * .exit.text is discarded at runtime, not link time,
|
| 120 | * to deal with references from __bug_table
|
| 121 | */
|
| 122 | .exit.text : {
|
| 123 | EXIT_TEXT
|
| 124 | }
|
| 125 |
|
| 126 | .exit.data : {
|
| 127 | EXIT_DATA
|
| 128 | }
|
| 129 |
|
| 130 | /*
|
| 131 | * struct alt_inst entries. From the header (alternative.h):
|
| 132 | * "Alternative instructions for different CPU types or capabilities"
|
| 133 | * Think locking instructions on spinlocks.
|
| 134 | * Note, that it is a part of __init region.
|
| 135 | */
|
| 136 | . = ALIGN(8);
|
| 137 | .altinstructions : {
|
| 138 | __alt_instructions = .;
|
| 139 | *(.altinstructions)
|
| 140 | __alt_instructions_end = .;
|
| 141 | }
|
| 142 |
|
| 143 | /*
|
| 144 | * And here are the replacement instructions. The linker sticks
|
| 145 | * them as binary blobs. The .altinstructions has enough data to
|
| 146 | * get the address and the length of them to patch the kernel safely.
|
| 147 | * Note, that it is a part of __init region.
|
| 148 | */
|
| 149 | .altinstr_replacement : {
|
| 150 | *(.altinstr_replacement)
|
| 151 | }
|
| 152 |
|
| 153 | |
| 154 | . = ALIGN(8);
|
| 155 | .stack_prot_table : {
|
| 156 | __stack_prot_start = .;
|
| 157 | KEEP(*(__stack_protector_loc))
|
| 158 | __stack_prot_end = .;
|
| 159 | }
|
| 160 | |
| 161 |
|
| 162 | . = ALIGN(8);
|
| 163 | .s390dbf_info : {
|
| 164 | __s390dbf_info = .;
|
| 165 | *(.s390dbf_info)
|
| 166 | __s390dbf_info_end = .;
|
| 167 | }
|
| 168 |
|
| 169 | /*
|
| 170 | * Table with the patch locations to undo expolines
|
| 171 | */
|
| 172 | . = ALIGN(4);
|
| 173 | .nospec_call_table : {
|
| 174 | __nospec_call_start = . ;
|
| 175 | *(.s390_indirect*)
|
| 176 | __nospec_call_end = . ;
|
| 177 | }
|
| 178 | .nospec_return_table : {
|
| 179 | __nospec_return_start = . ;
|
| 180 | *(.s390_return*)
|
| 181 | __nospec_return_end = . ;
|
| 182 | }
|
| 183 |
|
| 184 | BOOT_DATA
|
| 185 |
|
| 186 | /*
|
| 187 | * .amode31 section for code, data, ex_table that need to stay
|
| 188 | * below 2 GB, even when the kernel is relocated above 2 GB.
|
| 189 | */
|
| 190 | . = ALIGN(PAGE_SIZE);
|
| 191 | _samode31 = .;
|
| 192 | .amode31.text : {
|
| 193 | _stext_amode31 = .;
|
| 194 | *(.amode31.text)
|
| 195 | *(.amode31.text.*_indirect_*)
|
| 196 | . = ALIGN(PAGE_SIZE);
|
| 197 | _etext_amode31 = .;
|
| 198 | }
|
| 199 | . = ALIGN(16);
|
| 200 | .amode31.ex_table : {
|
| 201 | _start_amode31_ex_table = .;
|
| 202 | KEEP(*(.amode31.ex_table))
|
| 203 | _stop_amode31_ex_table = .;
|
| 204 | }
|
| 205 | . = ALIGN(PAGE_SIZE);
|
| 206 | .amode31.data : {
|
| 207 | *(.amode31.data)
|
| 208 | }
|
| 209 | . = _samode31 + AMODE31_SIZE;
|
| 210 | _eamode31 = .;
|
| 211 |
|
| 212 | /* early.c uses stsi, which requires page aligned data. */
|
| 213 | . = ALIGN(PAGE_SIZE);
|
| 214 | INIT_DATA_SECTION(0x100)
|
| 215 |
|
| 216 | RUNTIME_CONST_VARIABLES
|
| 217 |
|
| 218 | PERCPU_SECTION(0x100)
|
| 219 |
|
| 220 | . = ALIGN(PAGE_SIZE);
|
| 221 | __init_end = .; /* freed after init ends here */
|
| 222 |
|
| 223 | BSS_SECTION(PAGE_SIZE, 4 * PAGE_SIZE, PAGE_SIZE)
|
| 224 |
|
| 225 | . = ALIGN(PAGE_SIZE);
|
| 226 | _end = . ;
|
| 227 |
|
| 228 | /* Debugging sections. */
|
| 229 | STABS_DEBUG
|
| 230 | DWARF_DEBUG
|
| 231 | MODINFO
|
| 232 | ELF_DETAILS
|
| 233 |
|
| 234 | /*
|
| 235 | * Make sure that the .got.plt is either completely empty or it
|
| 236 | * contains only the three reserved double words.
|
| 237 | */
|
| 238 | .got.plt : {
|
| 239 | *(.got.plt)
|
| 240 | }
|
| 241 | ASSERT(SIZEOF(.got.plt) == 0 || SIZEOF(.got.plt) == 0x18, "Unexpected GOT/PLT entries detected!")
|
| 242 |
|
| 243 | /*
|
| 244 | * Sections that should stay zero sized, which is safer to
|
| 245 | * explicitly check instead of blindly discarding.
|
| 246 | */
|
| 247 | .plt : {
|
| 248 | *(.plt) *(.plt.*) *(.iplt) *(.igot .igot.plt)
|
| 249 | }
|
| 250 | ASSERT(SIZEOF(.plt) == 0, "Unexpected run-time procedure linkages detected!")
|
| 251 | .rela.dyn : {
|
| 252 | *(.rela.*) *(.rela_*)
|
| 253 | }
|
| 254 | ASSERT(SIZEOF(.rela.dyn) == 0, "Unexpected run-time relocations (.rela) detected!")
|
| 255 |
|
| 256 | /*
|
| 257 | * uncompressed image info used by the decompressor
|
| 258 | * it should match struct vmlinux_info
|
| 259 | */
|
| 260 | .vmlinux.info 0 (INFO) : {
|
| 261 | QUAD(startup_continue) /* entry */
|
| 262 | QUAD(__bss_start - _stext) /* image_size */
|
| 263 | QUAD(__bss_stop - __bss_start) /* bss_size */
|
| 264 | QUAD(__boot_data_start) /* bootdata_off */
|
| 265 | QUAD(__boot_data_end - __boot_data_start) /* bootdata_size */
|
| 266 | QUAD(__boot_data_preserved_start) /* bootdata_preserved_off */
|
| 267 | QUAD(__boot_data_preserved_end -
|
| 268 | __boot_data_preserved_start) /* bootdata_preserved_size */
|
| 269 | QUAD(__got_start) /* got_start */
|
| 270 | QUAD(__got_end) /* got_end */
|
| 271 | QUAD(_eamode31 - _samode31) /* amode31_size */
|
| 272 | QUAD(init_mm)
|
| 273 | QUAD(swapper_pg_dir)
|
| 274 | QUAD(invalid_pg_dir)
|
| 275 | QUAD(__alt_instructions)
|
| 276 | QUAD(__alt_instructions_end)
|
| 277 | |
| 278 | QUAD(__stack_prot_start)
|
| 279 | QUAD(__stack_prot_end)
|
| 280 | |
| 281 | |
| 282 | QUAD(kasan_early_shadow_page)
|
| 283 | QUAD(kasan_early_shadow_pte)
|
| 284 | QUAD(kasan_early_shadow_pmd)
|
| 285 | QUAD(kasan_early_shadow_pud)
|
| 286 | QUAD(kasan_early_shadow_p4d)
|
| 287 | |
| 288 | } :NONE
|
| 289 |
|
| 290 | /* Sections to be discarded */
|
| 291 | DISCARDS
|
| 292 | /DISCARD/ : {
|
| 293 | *(.eh_frame)
|
| 294 | *(.interp)
|
| 295 | }
|
| 296 | }
|