xref: /aosp_15_r20/external/coreboot/src/lib/program.ld (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1/* SPDX-License-Identifier: GPL-2.0-only */
2
3#include <memlayout.h>
4
5/* This file is included inside a SECTIONS block */
6
7/* First we place the code and read only data (typically const declared).
8 * This could theoretically be placed in rom.
9 * The '.' in '.text . : {' is actually significant to prevent missing some
10 * SoC's entry points due to artificial alignment restrictions, see
11 * https://sourceware.org/binutils/docs/ld/Output-Section-Address.html
12 */
13
14/* Starting with version 18 LLVM the combination -ffunction-section -mcmodel=large
15 * puts code and data in '.ltext, '.lrodata', '.ldata' and '.lbss'
16 */
17
18.text . : {
19	_program = .;
20	_text = .;
21#if !(ENV_X86 && ENV_BOOTBLOCK)
22	*(.init._start);
23	*(.init);
24	*(.init.*);
25#endif
26	*(.text._start);
27	*(.text.stage_entry);
28	KEEP(*(.metadata_hash_anchor));
29	*(.text);
30	*(.text.*);
31	*(.ltext);
32	*(.ltext.*);
33
34#if ENV_HAS_CBMEM
35	. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
36	_cbmem_init_hooks = .;
37	KEEP(*(.rodata.cbmem_init_hooks_early));
38	KEEP(*(.rodata.cbmem_init_hooks));
39	_ecbmem_init_hooks = .;
40	RECORD_SIZE(cbmem_init_hooks)
41#endif
42
43	. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
44	_rsbe_init_begin = .;
45	KEEP(*(.rsbe_init));
46	_ersbe_init_begin = .;
47	RECORD_SIZE(rsbe_init_begin)
48
49#if ENV_RAMSTAGE
50	. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
51	_pci_drivers = .;
52	KEEP(*(.rodata.pci_driver));
53	_epci_drivers = .;
54	RECORD_SIZE(pci_drivers)
55	. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
56	_cpu_drivers = .;
57	KEEP(*(.rodata.cpu_driver));
58	_ecpu_drivers = .;
59	RECORD_SIZE(cpu_drivers)
60#endif
61
62	. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
63	*(.rodata);
64	*(.rodata.*);
65	*(.lrodata);
66	*(.lrodata.*);
67	. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
68	_etext = .;
69	RECORD_SIZE(text)
70} : to_load
71
72#if ENV_RAMSTAGE && (CONFIG(COVERAGE) || CONFIG(ASAN_IN_RAMSTAGE))
73.ctors . : {
74	. = ALIGN(0x100);
75	__CTOR_LIST__ = .;
76	KEEP(*(.ctors));
77	LONG(0);
78	LONG(0);
79	__CTOR_END__ = .;
80} : to_load
81#endif
82
83/* Include data, bss, and heap in that order. Not defined for all stages. */
84#if !ENV_SEPARATE_DATA_AND_BSS
85.data . : {
86	. = ALIGN(ARCH_CACHELINE_ALIGN_SIZE);
87	_data = .;
88
89/*
90 * The postcar phase uses a stack value that is located in the relocatable
91 * module section. While the postcar stage could be linked like smm and
92 * other rmodules the postcar stage needs similar semantics of the more
93 * traditional stages in the coreboot infrastructure. Therefore it's easier
94 * to specialize this case.
95 */
96#if ENV_RMODULE || ENV_POSTCAR
97	_rmodule_params = .;
98	KEEP(*(.module_parameters));
99	_ermodule_params = .;
100	RECORD_SIZE(rmodule_params)
101#endif
102
103	*(.data);
104	*(.data.*);
105	*(.ldata);
106	*(.ldata.*);
107	*(.sdata);
108	*(.sdata.*);
109
110#if ENV_ROMSTAGE_OR_BEFORE
111	PROVIDE(_preram_cbmem_console = .);
112	PROVIDE(_epreram_cbmem_console = _preram_cbmem_console);
113	PROVIDE(_preram_cbmem_console_size = ABSOLUTE(0));
114#elif ENV_RAMSTAGE
115	. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
116	_bs_init_begin = .;
117	KEEP(*(.bs_init));
118	LONG(0);
119	LONG(0);
120	_ebs_init_begin = .;
121	RECORD_SIZE(bs_init_begin)
122#endif
123
124	. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
125	_edata = .;
126	RECORD_SIZE(data)
127} : to_load
128#endif
129
130#if !ENV_SEPARATE_DATA_AND_BSS
131.bss . (NOLOAD) : {
132	. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
133	_bss = .;
134	*(.bss)
135	*(.bss.*)
136	*(.lbss)
137	*(.lbss.*)
138	*(.sbss)
139	*(.sbss.*)
140	. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
141	_ebss = .;
142	RECORD_SIZE(bss)
143} : to_load
144#endif
145
146#if ENV_HAS_HEAP_SECTION
147.heap . (NOLOAD) : {
148	. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
149	_heap = .;
150	. += CONFIG_HEAP_SIZE;
151	. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
152	_eheap = .;
153	RECORD_SIZE(heap)
154} : to_load
155#endif
156
157#if ENV_RAMSTAGE && CONFIG(ASAN_IN_RAMSTAGE)
158	_shadow_size = (_eheap - _data) >> 3;
159	REGION(asan_shadow, ., _shadow_size, ARCH_POINTER_ALIGN_SIZE)
160#endif
161
162_eprogram = .;
163RECORD_SIZE(program)
164
165/* The stage cache drops CONFIG_HEAP_SIZE bytes from the end of the in-memory
166   image of the ramstage, so ensure that when moving that many bytes backwards
167   from the program end, we're in the heap (or later), in some region that
168   doesn't contain initialized code or data. */
169#if ENV_RAMSTAGE
170_bogus = ASSERT(_eprogram - CONFIG_HEAP_SIZE >= _heap,
171	"HEAP_SIZE and heap misaligned");
172#endif
173
174/* Discard the sections we don't need/want */
175
176zeroptr = 0;
177
178/DISCARD/ : {
179	*(.comment)
180	*(.comment.*)
181	*(.note)
182	*(.note.*)
183	*(.eh_frame);
184}
185