1/* 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright © 2019 Keith Packard 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above 14 * copyright notice, this list of conditions and the following 15 * disclaimer in the documentation and/or other materials provided 16 * with the distribution. 17 * 18 * 3. Neither the name of the copyright holder nor the names of its 19 * contributors may be used to endorse or promote products derived 20 * from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 26 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 31 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 33 * OF THE POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36ENTRY(@PREFIX@_start) 37 38/* 39 * These values should be provided by the application. We'll include 40 * some phony values here to make things link for testing 41 */ 42 43MEMORY 44{@INIT_MEMORY@ 45 flash (rx!w) : 46 ORIGIN = DEFINED(@PREFIX@__flash) ? @PREFIX@__flash : @DEFAULT_FLASH_ADDR@, 47 LENGTH = DEFINED(@PREFIX@__flash_size) ? @PREFIX@__flash_size : @DEFAULT_FLASH_SIZE@ 48 ram (w!rx) : 49 ORIGIN = DEFINED(@PREFIX@__ram) ? @PREFIX@__ram : @DEFAULT_RAM_ADDR@, 50 LENGTH = DEFINED(@PREFIX@__ram_size) ? @PREFIX@__ram_size : @DEFAULT_RAM_SIZE@ 51} 52 53PHDRS 54{@INIT_PHDRS@ 55 text PT_LOAD; 56 ram PT_LOAD; 57 ram_init PT_LOAD; 58 tls PT_TLS; 59} 60 61SECTIONS 62{ 63 PROVIDE(@PREFIX@__stack = ORIGIN(ram) + LENGTH(ram)); 64@INIT_SECTIONS@ 65 .text : { 66 67 /* code */ 68 *(.text.unlikely .text.unlikely.*) 69 *(.text.startup .text.startup.*) 70 *(.text .text.* .opd .opd.*) 71 *(.gnu.linkonce.t.*) 72 KEEP (*(.fini .fini.*)) 73 @PREFIX@__text_end = .; 74 75 PROVIDE (@PREFIX@__etext = @PREFIX@__text_end); 76 PROVIDE (@PREFIX@_etext = @PREFIX@__text_end); 77 PROVIDE (@PREFIX@etext = @PREFIX@__text_end); 78 79 /* Need to pre-align so that the symbols come after padding */ 80 . = ALIGN(@DEFAULT_ALIGNMENT@); 81 82 /* lists of constructors and destructors */ 83 PROVIDE_HIDDEN ( @PREFIX@__preinit_array_start = . ); 84 KEEP (*(.preinit_array)) 85 PROVIDE_HIDDEN ( @PREFIX@__preinit_array_end = . ); 86 87 PROVIDE_HIDDEN ( @PREFIX@__init_array_start = . ); 88 KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) 89 KEEP (*(.init_array .ctors)) 90 PROVIDE_HIDDEN ( @PREFIX@__init_array_end = . ); 91 92 PROVIDE_HIDDEN ( @PREFIX@__fini_array_start = . ); 93 KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) 94 KEEP (*(.fini_array .dtors)) 95 PROVIDE_HIDDEN ( @PREFIX@__fini_array_end = . ); 96 97 } >flash AT>flash :text 98 99 .rodata : { 100 101 /* read-only data */ 102 *(.rdata) 103 *(.rodata .rodata.*) 104 *(.gnu.linkonce.r.*) 105 106 *(.srodata.cst16) 107 *(.srodata.cst8) 108 *(.srodata.cst4) 109 *(.srodata.cst2) 110 *(.srodata .srodata.*) 111 112 } >flash AT>flash :text 113 114 .data.rel.ro : { 115 116 /* data that needs relocating */ 117 *(.data.rel.ro .data.rel.ro.*) 118 119 } >flash AT>flash :text 120 121 /* 122 * Needs to be in its own segment with the PLT entries first 123 * so that the linker will compute the offsets to those 124 * entries correctly. 125 */ 126 .got : { 127 *(.got.plt) 128 *(.got) 129 } >flash AT>flash :text 130 131 .toc : { 132 *(.toc .toc.*) 133 } >flash AT>flash :text 134 135 /* additional sections when compiling with C++ exception support */ 136 @CPP_START@ 137 .except_ordered : { 138 *(.gcc_except_table *.gcc_except_table.*) 139 *(.ARM.extab* .gnu.linkonce.armextab.*) 140 } >flash AT>flash :text 141 .eh_frame_hdr : { 142 PROVIDE_HIDDEN ( @PREFIX@__eh_frame_hdr_start = . ); 143 *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) 144 PROVIDE_HIDDEN ( @PREFIX@__eh_frame_hdr_end = . ); 145 } >flash AT>flash :text 146 .eh_frame : { 147 PROVIDE_HIDDEN ( @PREFIX@__eh_frame_start = . ); 148 KEEP (*(.eh_frame .eh_frame.*)) 149 PROVIDE_HIDDEN ( @PREFIX@__eh_frame_end = . ); 150 } >flash AT>flash :text 151 152 .except_unordered : { 153 . = ALIGN(@DEFAULT_ALIGNMENT@); 154 155 PROVIDE(@PREFIX@__exidx_start = .); 156 *(.ARM.exidx*) 157 PROVIDE(@PREFIX@__exidx_end = .); 158 } >flash AT>flash :text 159 @CPP_END@ 160 161 /* 162 * Data values which are preserved across reset 163 */ 164 .preserve (NOLOAD) : { 165 PROVIDE(@PREFIX@__preserve_start__ = .); 166 KEEP(*(SORT_BY_NAME(.preserve.*))) 167 KEEP(*(.preserve)) 168 PROVIDE(@PREFIX@__preserve_end__ = .); 169 } >ram AT>ram :ram 170 171 .data : @BFD_START@ ALIGN_WITH_INPUT @BFD_END@ { 172 *(.data .data.*) 173 *(.gnu.linkonce.d.*) 174 175 /* Need to pre-align so that the symbols come after padding */ 176 . = ALIGN(@DEFAULT_ALIGNMENT@); 177 178 PROVIDE( @PREFIX@__global_pointer$ = . + 0x800 ); 179 PROVIDE( @PREFIX@_gp = . + 0x8000); 180 *(.sdata .sdata.* .sdata2.*) 181 *(.gnu.linkonce.s.*) 182 } >ram AT>flash :ram_init 183 PROVIDE(@PREFIX@__data_start = ADDR(.data)); 184 PROVIDE(@PREFIX@__data_source = LOADADDR(.data)); 185 186 /* Thread local initialized data. This gets 187 * space allocated as it is expected to be placed 188 * in ram to be used as a template for TLS data blocks 189 * allocated at runtime. We're slightly abusing that 190 * by placing the data in flash where it will be copied 191 * into the allocate ram addresses by the existing 192 * data initialization code in crt0. 193 * BFD includes .tbss alignment when computing .tdata 194 * alignment, but for ld.lld we have to explicitly pad 195 * as it only guarantees usage as a TLS template works 196 * rather than supporting this use case. 197 */ 198 .tdata : @LLD_START@ ALIGN(@PREFIX@__tls_align) @LLD_END@ @BFD_START@ ALIGN_WITH_INPUT @BFD_END@ { 199 *(.tdata .tdata.* .gnu.linkonce.td.*) 200 PROVIDE(@PREFIX@__data_end = .); 201 PROVIDE(@PREFIX@__tdata_end = .); 202 } >ram AT>flash :tls :ram_init 203 PROVIDE( @PREFIX@__tls_base = ADDR(.tdata)); 204 PROVIDE( @PREFIX@__tdata_start = ADDR(.tdata)); 205 PROVIDE( @PREFIX@__tdata_source = LOADADDR(.tdata) ); 206 PROVIDE( @PREFIX@__tdata_source_end = LOADADDR(.tdata) + SIZEOF(.tdata) ); 207 PROVIDE( @PREFIX@__data_source_end = @PREFIX@__tdata_source_end ); 208 PROVIDE( @PREFIX@__tdata_size = SIZEOF(.tdata) ); 209 210 PROVIDE( @PREFIX@__edata = @PREFIX@__data_end ); 211 PROVIDE( @PREFIX@_edata = @PREFIX@__data_end ); 212 PROVIDE( @PREFIX@edata = @PREFIX@__data_end ); 213 PROVIDE( @PREFIX@__data_size = @PREFIX@__data_end - @PREFIX@__data_start ); 214 PROVIDE( @PREFIX@__data_source_size = @PREFIX@__data_source_end - @PREFIX@__data_source ); 215 216 .tbss (NOLOAD) : { 217 *(.tbss .tbss.* .gnu.linkonce.tb.*) 218 *(.tcommon) 219 PROVIDE( @PREFIX@__tls_end = . ); 220 PROVIDE( @PREFIX@__tbss_end = . ); 221 } >ram AT>ram :tls :ram 222 PROVIDE( @PREFIX@__bss_start = ADDR(.tbss)); 223 PROVIDE( @PREFIX@__tbss_start = ADDR(.tbss)); 224 PROVIDE( @PREFIX@__tbss_offset = ADDR(.tbss) - ADDR(.tdata) ); 225 PROVIDE( @PREFIX@__tbss_size = SIZEOF(.tbss) ); 226 PROVIDE( @PREFIX@__tls_size = @PREFIX@__tls_end - @PREFIX@__tls_base ); 227 PROVIDE( @PREFIX@__tls_align = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)) ); 228 PROVIDE( @PREFIX@__tls_size_align = (@PREFIX@__tls_size + @PREFIX@__tls_align - 1) & ~(@PREFIX@__tls_align - 1)); 229 PROVIDE( @PREFIX@__arm32_tls_tcb_offset = MAX(8, @PREFIX@__tls_align) ); 230 PROVIDE( @PREFIX@__arm64_tls_tcb_offset = MAX(16, @PREFIX@__tls_align) ); 231 232 /* 233 * Unlike ld.lld, ld.bfd does not advance the location counter for 234 * .tbss, but we actually need memory allocated for .tbss as we use 235 * it for the initial TLS storage. 236 * Create special section here just to make room. 237 */ 238 @BFD_START@ 239 .tbss_space (NOLOAD) : { 240 . = ADDR(.tbss); 241 . = . + SIZEOF(.tbss); 242 } >ram AT>ram :ram 243 @BFD_END@ 244 .bss (NOLOAD) : { 245 *(.sbss*) 246 *(.gnu.linkonce.sb.*) 247 *(.bss .bss.*) 248 *(.gnu.linkonce.b.*) 249 *(COMMON) 250 251 /* Align the heap */ 252 . = ALIGN(@DEFAULT_ALIGNMENT@); 253 @PREFIX@__bss_end = .; 254 } >ram AT>ram :ram 255 PROVIDE( @PREFIX@__non_tls_bss_start = ADDR(.bss) ); 256 PROVIDE( @PREFIX@__end = @PREFIX@__bss_end ); 257 @PREFIX@_end = @PREFIX@__bss_end; 258 PROVIDE( @PREFIX@end = @PREFIX@__bss_end ); 259 PROVIDE( @PREFIX@__bss_size = @PREFIX@__bss_end - @PREFIX@__bss_start ); 260 261 /* Make the rest of memory available for heap storage */ 262 PROVIDE (@PREFIX@__heap_start = @PREFIX@__end); 263 PROVIDE (@PREFIX@__heap_end = @PREFIX@__stack - (DEFINED(@PREFIX@__stack_size) ? @PREFIX@__stack_size : @DEFAULT_STACK_SIZE@)); 264 PROVIDE (@PREFIX@__heap_size = @PREFIX@__heap_end - @PREFIX@__heap_start); 265 266 /* Allow a minimum heap size to be specified */ 267 .heap (NOLOAD) : { 268 . += (DEFINED(@PREFIX@__heap_size_min) ? @PREFIX@__heap_size_min : 0); 269 } >ram :ram 270 271 /* Define a stack region to make sure it fits in memory */ 272 .stack (NOLOAD) : { 273 . += (DEFINED(@PREFIX@__stack_size) ? @PREFIX@__stack_size : @DEFAULT_STACK_SIZE@); 274 } >ram :ram 275 276 /* Throw away C++ exception handling information */ 277 278 @C_START@ 279 280 /DISCARD/ : { 281 *(.note .note.*) 282 *(.eh_frame .eh_frame.*) 283 *(.ARM.extab* .gnu.linkonce.armextab.*) 284 *(.ARM.exidx*) 285 } 286 287 @C_END@ 288 289 /* Stabs debugging sections. */ 290 .stab 0 : { *(.stab) } 291 .stabstr 0 : { *(.stabstr) } 292 .stab.excl 0 : { *(.stab.excl) } 293 .stab.exclstr 0 : { *(.stab.exclstr) } 294 .stab.index 0 : { *(.stab.index) } 295 .stab.indexstr 0 : { *(.stab.indexstr) } 296 .comment 0 : { *(.comment) } 297 .gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) } 298 /* DWARF debug sections. 299 Symbols in the DWARF debugging sections are relative to the beginning 300 of the section so we begin them at 0. */ 301 /* DWARF 1. */ 302 .debug 0 : { *(.debug) } 303 .line 0 : { *(.line) } 304 /* GNU DWARF 1 extensions. */ 305 .debug_srcinfo 0 : { *(.debug_srcinfo) } 306 .debug_sfnames 0 : { *(.debug_sfnames) } 307 /* DWARF 1.1 and DWARF 2. */ 308 .debug_aranges 0 : { *(.debug_aranges) } 309 .debug_pubnames 0 : { *(.debug_pubnames) } 310 /* DWARF 2. */ 311 .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } 312 .debug_abbrev 0 : { *(.debug_abbrev) } 313 .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) } 314 .debug_frame 0 : { *(.debug_frame) } 315 .debug_str 0 : { *(.debug_str) } 316 .debug_loc 0 : { *(.debug_loc) } 317 .debug_macinfo 0 : { *(.debug_macinfo) } 318 /* SGI/MIPS DWARF 2 extensions. */ 319 .debug_weaknames 0 : { *(.debug_weaknames) } 320 .debug_funcnames 0 : { *(.debug_funcnames) } 321 .debug_typenames 0 : { *(.debug_typenames) } 322 .debug_varnames 0 : { *(.debug_varnames) } 323 /* DWARF 3. */ 324 .debug_pubtypes 0 : { *(.debug_pubtypes) } 325 .debug_ranges 0 : { *(.debug_ranges) } 326 /* DWARF 5. */ 327 .debug_addr 0 : { *(.debug_addr) } 328 .debug_line_str 0 : { *(.debug_line_str) } 329 .debug_loclists 0 : { *(.debug_loclists) } 330 .debug_macro 0 : { *(.debug_macro) } 331 .debug_names 0 : { *(.debug_names) } 332 .debug_rnglists 0 : { *(.debug_rnglists) } 333 .debug_str_offsets 0 : { *(.debug_str_offsets) } 334 .debug_sup 0 : { *(.debug_sup) } 335 .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) } 336} 337/* 338 * Check that sections that are copied from flash to RAM have matching 339 * padding, so that a single memcpy() of __data_size copies the correct bytes. 340 */ 341ASSERT( @PREFIX@__data_size == @PREFIX@__data_source_size, 342 "ERROR: .data/.tdata flash size does not match RAM size"); 343