/ src / lib / program.ld
program.ld
  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  	. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
 61  	_cfr_forms = .;
 62  	KEEP(*(.rodata.cfr_forms));
 63  	_ecfr_forms = .;
 64  	RECORD_SIZE(cfr_forms)
 65  #endif
 66  
 67  	. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
 68  	*(.rodata);
 69  	*(.rodata.*);
 70  	*(.lrodata);
 71  	*(.lrodata.*);
 72  	. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
 73  	_etext = .;
 74  	RECORD_SIZE(text)
 75  } : to_load
 76  
 77  #if ENV_RAMSTAGE && (CONFIG(COVERAGE) || CONFIG(ASAN_IN_RAMSTAGE))
 78  .ctors . : {
 79  	. = ALIGN(0x100);
 80  	__CTOR_LIST__ = .;
 81  	KEEP(*(.ctors));
 82  	LONG(0);
 83  	LONG(0);
 84  	__CTOR_END__ = .;
 85  } : to_load
 86  #endif
 87  
 88  /* Include data, bss, and heap in that order. Not defined for all stages. */
 89  #if !ENV_SEPARATE_DATA_AND_BSS
 90  .data . : {
 91  	. = ALIGN(ARCH_CACHELINE_ALIGN_SIZE);
 92  	_data = .;
 93  
 94  /*
 95   * The postcar phase uses a stack value that is located in the relocatable
 96   * module section. While the postcar stage could be linked like smm and
 97   * other rmodules the postcar stage needs similar semantics of the more
 98   * traditional stages in the coreboot infrastructure. Therefore it's easier
 99   * to specialize this case.
100   */
101  #if ENV_RMODULE || ENV_POSTCAR
102  	_rmodule_params = .;
103  	KEEP(*(.module_parameters));
104  	_ermodule_params = .;
105  	RECORD_SIZE(rmodule_params)
106  #endif
107  
108  	*(.data);
109  	*(.data.*);
110  	*(.ldata);
111  	*(.ldata.*);
112  	*(.sdata);
113  	*(.sdata.*);
114  
115  #if ENV_ROMSTAGE_OR_BEFORE
116  	PROVIDE(_preram_cbmem_console = .);
117  	PROVIDE(_epreram_cbmem_console = _preram_cbmem_console);
118  	PROVIDE(_preram_cbmem_console_size = ABSOLUTE(0));
119  #elif ENV_RAMSTAGE
120  	. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
121  	_bs_init_begin = .;
122  	KEEP(*(.bs_init));
123  	LONG(0);
124  	LONG(0);
125  	_ebs_init_begin = .;
126  	RECORD_SIZE(bs_init_begin)
127  #endif
128  
129  	. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
130  	_edata = .;
131  	RECORD_SIZE(data)
132  } : to_load
133  #endif
134  
135  #if !ENV_SEPARATE_DATA_AND_BSS
136  .bss . (NOLOAD) : {
137  	. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
138  	_bss = .;
139  	*(.bss)
140  	*(.bss.*)
141  	*(.lbss)
142  	*(.lbss.*)
143  	*(.sbss)
144  	*(.sbss.*)
145  	. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
146  	_ebss = .;
147  	RECORD_SIZE(bss)
148  } : to_load
149  #endif
150  
151  #if ENV_HAS_HEAP_SECTION
152  .heap . (NOLOAD) : {
153  	. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
154  	_heap = .;
155  	. += CONFIG_HEAP_SIZE;
156  	. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
157  	_eheap = .;
158  	RECORD_SIZE(heap)
159  } : to_load
160  #endif
161  
162  #if ENV_RAMSTAGE && CONFIG(ASAN_IN_RAMSTAGE)
163  	_shadow_size = (_eheap - _data) >> 3;
164  	REGION(asan_shadow, ., _shadow_size, ARCH_POINTER_ALIGN_SIZE)
165  #endif
166  
167  _eprogram = .;
168  RECORD_SIZE(program)
169  
170  /* The stage cache drops CONFIG_HEAP_SIZE bytes from the end of the in-memory
171     image of the ramstage, so ensure that when moving that many bytes backwards
172     from the program end, we're in the heap (or later), in some region that
173     doesn't contain initialized code or data. */
174  #if ENV_RAMSTAGE
175  _bogus = ASSERT(_eprogram - CONFIG_HEAP_SIZE >= _heap,
176  	"HEAP_SIZE and heap misaligned");
177  #endif
178  
179  /* Discard the sections we don't need/want */
180  
181  zeroptr = 0;
182  
183  /DISCARD/ : {
184  	*(.comment)
185  	*(.comment.*)
186  	*(.note)
187  	*(.note.*)
188  	*(.eh_frame);
189  }