Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifdef CONFIG_PPC64
0003 #define PROVIDE32(x)    PROVIDE(__unused__##x)
0004 #else
0005 #define PROVIDE32(x)    PROVIDE(x)
0006 #endif
0007 
0008 #define BSS_FIRST_SECTIONS *(.bss.prominit)
0009 #define EMITS_PT_NOTE
0010 #define RO_EXCEPTION_TABLE_ALIGN    0
0011 
0012 #define SOFT_MASK_TABLE(align)                      \
0013     . = ALIGN(align);                       \
0014     __soft_mask_table : AT(ADDR(__soft_mask_table) - LOAD_OFFSET) { \
0015         __start___soft_mask_table = .;              \
0016         KEEP(*(__soft_mask_table))              \
0017         __stop___soft_mask_table = .;               \
0018     }
0019 
0020 #define RESTART_TABLE(align)                        \
0021     . = ALIGN(align);                       \
0022     __restart_table : AT(ADDR(__restart_table) - LOAD_OFFSET) { \
0023         __start___restart_table = .;                \
0024         KEEP(*(__restart_table))                \
0025         __stop___restart_table = .;             \
0026     }
0027 
0028 #include <asm/page.h>
0029 #include <asm-generic/vmlinux.lds.h>
0030 #include <asm/cache.h>
0031 #include <asm/thread_info.h>
0032 
0033 #define STRICT_ALIGN_SIZE   (1 << CONFIG_DATA_SHIFT)
0034 
0035 ENTRY(_stext)
0036 
0037 PHDRS {
0038     text PT_LOAD FLAGS(7); /* RWX */
0039     note PT_NOTE FLAGS(0);
0040 }
0041 
0042 #ifdef CONFIG_PPC64
0043 OUTPUT_ARCH(powerpc:common64)
0044 jiffies = jiffies_64;
0045 #else
0046 OUTPUT_ARCH(powerpc:common)
0047 jiffies = jiffies_64 + 4;
0048 #endif
0049 SECTIONS
0050 {
0051     . = KERNELBASE;
0052 
0053 /*
0054  * Text, read only data and other permanent read-only sections
0055  */
0056 
0057     _text = .;
0058     _stext = .;
0059 
0060     /*
0061      * Head text.
0062      * This needs to be in its own output section to avoid ld placing
0063      * branch trampoline stubs randomly throughout the fixed sections,
0064      * which it will do (even if the branch comes from another section)
0065      * in order to optimize stub generation.
0066      */
0067     .head.text : AT(ADDR(.head.text) - LOAD_OFFSET) {
0068 #ifdef CONFIG_PPC64
0069         KEEP(*(.head.text.first_256B));
0070 #ifdef CONFIG_PPC_BOOK3E
0071 #else
0072         KEEP(*(.head.text.real_vectors));
0073         *(.head.text.real_trampolines);
0074         KEEP(*(.head.text.virt_vectors));
0075         *(.head.text.virt_trampolines);
0076 # if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
0077         KEEP(*(.head.data.fwnmi_page));
0078 # endif
0079 #endif
0080 #else /* !CONFIG_PPC64 */
0081         HEAD_TEXT
0082 #endif
0083     } :text
0084 
0085     __head_end = .;
0086 
0087 #ifdef CONFIG_PPC64
0088     /*
0089      * ALIGN(0) overrides the default output section alignment because
0090      * this needs to start right after .head.text in order for fixed
0091      * section placement to work.
0092      */
0093     .text ALIGN(0) : AT(ADDR(.text) - LOAD_OFFSET) {
0094 #ifdef CONFIG_LD_HEAD_STUB_CATCH
0095         KEEP(*(.linker_stub_catch));
0096         . = . ;
0097 #endif
0098 
0099 #else
0100     .text : AT(ADDR(.text) - LOAD_OFFSET) {
0101         ALIGN_FUNCTION();
0102 #endif
0103         /* careful! __ftr_alt_* sections need to be close to .text */
0104         *(.text.hot .text.hot.* TEXT_MAIN .text.fixup .text.unlikely .text.unlikely.* .fixup __ftr_alt_* .ref.text);
0105 #ifdef CONFIG_PPC64
0106         *(.tramp.ftrace.text);
0107 #endif
0108         NOINSTR_TEXT
0109         SCHED_TEXT
0110         CPUIDLE_TEXT
0111         LOCK_TEXT
0112         KPROBES_TEXT
0113         IRQENTRY_TEXT
0114         SOFTIRQENTRY_TEXT
0115         /*
0116          * -Os builds call FP save/restore functions. The powerpc64
0117          * linker generates those on demand in the .sfpr section.
0118          * .sfpr gets placed at the beginning of a group of input
0119          * sections, which can break start-of-text offset if it is
0120          * included with the main text sections, so put it by itself.
0121          */
0122         *(.sfpr);
0123         MEM_KEEP(init.text)
0124         MEM_KEEP(exit.text)
0125 
0126 #ifdef CONFIG_PPC32
0127         *(.got1)
0128         __got2_start = .;
0129         *(.got2)
0130         __got2_end = .;
0131 #endif /* CONFIG_PPC32 */
0132 
0133     } :text
0134 
0135     . = ALIGN(PAGE_SIZE);
0136     _etext = .;
0137     PROVIDE32 (etext = .);
0138 
0139     /* Read-only data */
0140     RO_DATA(PAGE_SIZE)
0141 
0142 #ifdef CONFIG_PPC64
0143     SOFT_MASK_TABLE(8)
0144     RESTART_TABLE(8)
0145 
0146     .opd : AT(ADDR(.opd) - LOAD_OFFSET) {
0147         __start_opd = .;
0148         KEEP(*(.opd))
0149         __end_opd = .;
0150     }
0151 
0152     . = ALIGN(8);
0153     __stf_entry_barrier_fixup : AT(ADDR(__stf_entry_barrier_fixup) - LOAD_OFFSET) {
0154         __start___stf_entry_barrier_fixup = .;
0155         *(__stf_entry_barrier_fixup)
0156         __stop___stf_entry_barrier_fixup = .;
0157     }
0158 
0159     . = ALIGN(8);
0160     __uaccess_flush_fixup : AT(ADDR(__uaccess_flush_fixup) - LOAD_OFFSET) {
0161         __start___uaccess_flush_fixup = .;
0162         *(__uaccess_flush_fixup)
0163         __stop___uaccess_flush_fixup = .;
0164     }
0165 
0166     . = ALIGN(8);
0167     __entry_flush_fixup : AT(ADDR(__entry_flush_fixup) - LOAD_OFFSET) {
0168         __start___entry_flush_fixup = .;
0169         *(__entry_flush_fixup)
0170         __stop___entry_flush_fixup = .;
0171     }
0172 
0173     . = ALIGN(8);
0174     __scv_entry_flush_fixup : AT(ADDR(__scv_entry_flush_fixup) - LOAD_OFFSET) {
0175         __start___scv_entry_flush_fixup = .;
0176         *(__scv_entry_flush_fixup)
0177         __stop___scv_entry_flush_fixup = .;
0178     }
0179 
0180     . = ALIGN(8);
0181     __stf_exit_barrier_fixup : AT(ADDR(__stf_exit_barrier_fixup) - LOAD_OFFSET) {
0182         __start___stf_exit_barrier_fixup = .;
0183         *(__stf_exit_barrier_fixup)
0184         __stop___stf_exit_barrier_fixup = .;
0185     }
0186 
0187     . = ALIGN(8);
0188     __rfi_flush_fixup : AT(ADDR(__rfi_flush_fixup) - LOAD_OFFSET) {
0189         __start___rfi_flush_fixup = .;
0190         *(__rfi_flush_fixup)
0191         __stop___rfi_flush_fixup = .;
0192     }
0193 #endif /* CONFIG_PPC64 */
0194 
0195 #ifdef CONFIG_PPC_BARRIER_NOSPEC
0196     . = ALIGN(8);
0197     __spec_barrier_fixup : AT(ADDR(__spec_barrier_fixup) - LOAD_OFFSET) {
0198         __start___barrier_nospec_fixup = .;
0199         *(__barrier_nospec_fixup)
0200         __stop___barrier_nospec_fixup = .;
0201     }
0202 #endif /* CONFIG_PPC_BARRIER_NOSPEC */
0203 
0204 #ifdef CONFIG_PPC_FSL_BOOK3E
0205     . = ALIGN(8);
0206     __spec_btb_flush_fixup : AT(ADDR(__spec_btb_flush_fixup) - LOAD_OFFSET) {
0207         __start__btb_flush_fixup = .;
0208         *(__btb_flush_fixup)
0209         __stop__btb_flush_fixup = .;
0210     }
0211 #endif
0212 
0213 /*
0214  * Init sections discarded at runtime
0215  */
0216     . = ALIGN(STRICT_ALIGN_SIZE);
0217     __init_begin = .;
0218     . = ALIGN(PAGE_SIZE);
0219     .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
0220         _sinittext = .;
0221         INIT_TEXT
0222 
0223         /*
0224          *.init.text might be RO so we must ensure this section ends on
0225          * a page boundary.
0226          */
0227         . = ALIGN(PAGE_SIZE);
0228         _einittext = .;
0229 #ifdef CONFIG_PPC64
0230         *(.tramp.ftrace.init);
0231 #endif
0232     } :text
0233 
0234     /* .exit.text is discarded at runtime, not link time,
0235      * to deal with references from __bug_table
0236      */
0237     .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
0238         EXIT_TEXT
0239     }
0240 
0241     . = ALIGN(PAGE_SIZE);
0242 
0243     INIT_DATA_SECTION(16)
0244 
0245     . = ALIGN(8);
0246     __ftr_fixup : AT(ADDR(__ftr_fixup) - LOAD_OFFSET) {
0247         __start___ftr_fixup = .;
0248         KEEP(*(__ftr_fixup))
0249         __stop___ftr_fixup = .;
0250     }
0251     . = ALIGN(8);
0252     __mmu_ftr_fixup : AT(ADDR(__mmu_ftr_fixup) - LOAD_OFFSET) {
0253         __start___mmu_ftr_fixup = .;
0254         KEEP(*(__mmu_ftr_fixup))
0255         __stop___mmu_ftr_fixup = .;
0256     }
0257     . = ALIGN(8);
0258     __lwsync_fixup : AT(ADDR(__lwsync_fixup) - LOAD_OFFSET) {
0259         __start___lwsync_fixup = .;
0260         KEEP(*(__lwsync_fixup))
0261         __stop___lwsync_fixup = .;
0262     }
0263 #ifdef CONFIG_PPC64
0264     . = ALIGN(8);
0265     __fw_ftr_fixup : AT(ADDR(__fw_ftr_fixup) - LOAD_OFFSET) {
0266         __start___fw_ftr_fixup = .;
0267         KEEP(*(__fw_ftr_fixup))
0268         __stop___fw_ftr_fixup = .;
0269     }
0270 #endif
0271 
0272     PERCPU_SECTION(L1_CACHE_BYTES)
0273 
0274     . = ALIGN(8);
0275     .machine.desc : AT(ADDR(.machine.desc) - LOAD_OFFSET) {
0276         __machine_desc_start = . ;
0277         KEEP(*(.machine.desc))
0278         __machine_desc_end = . ;
0279     }
0280 #ifdef CONFIG_RELOCATABLE
0281     . = ALIGN(8);
0282     .dynsym : AT(ADDR(.dynsym) - LOAD_OFFSET)
0283     {
0284         __dynamic_symtab = .;
0285         *(.dynsym)
0286     }
0287     .dynstr : AT(ADDR(.dynstr) - LOAD_OFFSET) { *(.dynstr) }
0288     .dynamic : AT(ADDR(.dynamic) - LOAD_OFFSET)
0289     {
0290         __dynamic_start = .;
0291         *(.dynamic)
0292     }
0293     .hash : AT(ADDR(.hash) - LOAD_OFFSET) { *(.hash) }
0294     .gnu.hash : AT(ADDR(.gnu.hash) - LOAD_OFFSET) { *(.gnu.hash) }
0295     .interp : AT(ADDR(.interp) - LOAD_OFFSET) { *(.interp) }
0296     .rela.dyn : AT(ADDR(.rela.dyn) - LOAD_OFFSET)
0297     {
0298         __rela_dyn_start = .;
0299         *(.rela*)
0300     }
0301 #endif
0302     /* .exit.data is discarded at runtime, not link time,
0303      * to deal with references from .exit.text
0304      */
0305     .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) {
0306         EXIT_DATA
0307     }
0308 
0309     /* freed after init ends here */
0310     . = ALIGN(PAGE_SIZE);
0311     __init_end = .;
0312 
0313 /*
0314  * And now the various read/write data
0315  */
0316 
0317     . = ALIGN(PAGE_SIZE);
0318     _sdata = .;
0319 
0320 #ifdef CONFIG_PPC32
0321     .data : AT(ADDR(.data) - LOAD_OFFSET) {
0322         DATA_DATA
0323         *(.data.rel*)
0324         *(SDATA_MAIN)
0325         *(.sdata2)
0326         *(.got.plt) *(.got)
0327         *(.plt)
0328         *(.branch_lt)
0329     }
0330 #else
0331     .data : AT(ADDR(.data) - LOAD_OFFSET) {
0332         DATA_DATA
0333         *(.data.rel*)
0334         *(.toc1)
0335         *(.branch_lt)
0336     }
0337 
0338     .got : AT(ADDR(.got) - LOAD_OFFSET) ALIGN(256) {
0339         *(.got)
0340 #ifndef CONFIG_RELOCATABLE
0341         __prom_init_toc_start = .;
0342         arch/powerpc/kernel/prom_init.o*(.toc)
0343         __prom_init_toc_end = .;
0344 #endif
0345         *(.toc)
0346     }
0347 #endif
0348 
0349     /* The initial task and kernel stack */
0350     INIT_TASK_DATA_SECTION(THREAD_ALIGN)
0351 
0352     .data..page_aligned : AT(ADDR(.data..page_aligned) - LOAD_OFFSET) {
0353         PAGE_ALIGNED_DATA(PAGE_SIZE)
0354     }
0355 
0356     .data..cacheline_aligned : AT(ADDR(.data..cacheline_aligned) - LOAD_OFFSET) {
0357         CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES)
0358     }
0359 
0360     .data..read_mostly : AT(ADDR(.data..read_mostly) - LOAD_OFFSET) {
0361         READ_MOSTLY_DATA(L1_CACHE_BYTES)
0362     }
0363 
0364     . = ALIGN(PAGE_SIZE);
0365     .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
0366         NOSAVE_DATA
0367     }
0368 
0369     BUG_TABLE
0370 
0371     . = ALIGN(PAGE_SIZE);
0372     _edata  =  .;
0373     PROVIDE32 (edata = .);
0374 
0375 /*
0376  * And finally the bss
0377  */
0378 
0379     BSS_SECTION(0, 0, 0)
0380 
0381     . = ALIGN(PAGE_SIZE);
0382     _end = . ;
0383     PROVIDE32 (end = .);
0384 
0385     STABS_DEBUG
0386     DWARF_DEBUG
0387     ELF_DETAILS
0388 
0389     DISCARDS
0390     /DISCARD/ : {
0391         *(*.EMB.apuinfo)
0392         *(.glink .iplt .plt .rela* .comment)
0393         *(.gnu.version*)
0394         *(.gnu.attributes)
0395         *(.eh_frame)
0396     }
0397 }