1/* 2 * Arm SCP/MCP Software 3 * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved. 4 * 5 * SPDX-License-Identifier: BSD-3-Clause 6 * 7 * Description: 8 * GNU LD linker script. 9 */ 10 11#include <arch_scatter.h> 12 13ENTRY(arch_exception_reset) 14 15MEMORY { 16#if FMW_MEM_MODE == ARCH_MEM_MODE_SINGLE_REGION 17 /* 18 * Single region memory layout: 19 * - MEM0 accepts: 20 * - Read-only sections 21 * - Read-write sections 22 * - Executable sections 23 */ 24 25 mem0 (rwx) : ORIGIN = FMW_MEM0_BASE, LENGTH = FMW_MEM0_SIZE 26#elif FMW_MEM_MODE == ARCH_MEM_MODE_DUAL_REGION_RELOCATION 27 /* 28 * Dual region memory layout with initialized data relocation: 29 * - MEM0 accepts: 30 * - Read-only sections 31 * - Executable sections 32 * 33 * - MEM1 accepts: 34 * - Read-write sections 35 */ 36 37 mem0 (rx) : ORIGIN = FMW_MEM0_BASE, LENGTH = FMW_MEM0_SIZE 38 mem1 (w) : ORIGIN = FMW_MEM1_BASE, LENGTH = FMW_MEM1_SIZE 39#elif FMW_MEM_MODE == ARCH_MEM_MODE_DUAL_REGION_NO_RELOCATION 40 /* 41 * Dual region memory layout without initialized data relocation: 42 * - MEM0 accepts: 43 * - Executable sections 44 * 45 * - MEM1 accepts: 46 * - Read-only sections 47 * - Read-write sections 48 */ 49 50 mem0 (x) : ORIGIN = FMW_MEM0_BASE, LENGTH = FMW_MEM0_SIZE 51 mem1 (rw) : ORIGIN = FMW_MEM1_BASE, LENGTH = FMW_MEM1_SIZE 52#endif 53} 54 55#if FMW_MEM_MODE == ARCH_MEM_MODE_SINGLE_REGION 56 REGION_ALIAS("r", mem0); 57 REGION_ALIAS("w", mem0); 58 REGION_ALIAS("x", mem0); 59#elif FMW_MEM_MODE == ARCH_MEM_MODE_DUAL_REGION_RELOCATION 60 REGION_ALIAS("r", mem0); 61 REGION_ALIAS("w", mem1); 62 REGION_ALIAS("x", mem0); 63#elif FMW_MEM_MODE == ARCH_MEM_MODE_DUAL_REGION_NO_RELOCATION 64 REGION_ALIAS("r", mem1); 65 REGION_ALIAS("w", mem1); 66 REGION_ALIAS("x", mem0); 67#endif 68 69SECTIONS { 70 /* 71 * Variables defined here: 72 * - __data_load__: Load address of .data 73 * - __data_start__: Start address of .data 74 * - __data_end__: End address of .data and .data-like orphans 75 * - __bss_start__: Start address of .bss 76 * - __bss_end__: End address of .bss and .bss-like orphans 77 * - __stackheap_start__: Start address of .stackheap 78 * - __stackheap_end__: End address of .stackheap 79 * - __stack: Initial stack pointer 80 */ 81 82 .exceptions : { 83 KEEP(*(.exceptions)) 84 } > x 85 86 .text : { 87 *(.text .text.*) 88 } > x 89 90#ifdef __clang__ 91 .eh_frame : { 92 (.eh_frame) 93 } > x 94 95 .ARM.exidx : { 96 (.ARM.exidx) 97 } > x 98#endif 99 100 /* 101 * .init and .fini below refer to sections containing functions meant to 102 * run before program startup and after program shutdown. While we don't use 103 * these functions, Newlib refers to them unconditionally and they are, 104 * perhaps counterintuitively, stripped from the binary unless marked as 105 * KEEP. 106 */ 107 108 .init : { 109 KEEP(*(.init)) 110 } > x 111 112 .fini : { 113 KEEP(*(.fini)) 114 } > x 115 116 .init_array : { 117 __init_array_start = .; 118 KEEP(*(.init_array*)) 119 __init_array_end = .; 120 } > r 121 122 .fini_array : { 123 __fini_array_start = .; 124 KEEP(*(.fini_array)) 125 __fini_array_end = .; 126 } > r 127 128 .rodata : { 129 *(.rodata .rodata.*) 130 } > r 131 132 .data : { 133 __data_load__ = LOADADDR(.data); 134 __data_start__ = ABSOLUTE(.); 135 136 *(.data .data.*) 137 } > w AT> r 138 139 .bss (NOLOAD) : { 140 __bss_start__ = ABSOLUTE(.); 141 142 *(.bss .bss.*) 143 } > w 144 145 .stackheap (NOLOAD) : { 146 __stackheap_start__ = ABSOLUTE(.); 147 148 . = ORIGIN(w) + LENGTH(w); 149 150 __stackheap_end__ = ABSOLUTE(.); 151 } > w 152 153 /* 154 * By default the linker places orphan sections after the section with the 155 * closest matching attributes. Calculating the end of a section based on 156 * the beginning of the next one that we know about means we can include BSS 157 * and DATA sections that we don't know about in these values. 158 */ 159 160 __data_end__ = __bss_start__; 161 __bss_end__ = __stackheap_start__; 162 163 __stack = __stackheap_end__; 164} 165