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