Starting with version 18 LLVM puts code and data generated with -ffunction-section -mcmodel=large inside sections with an 'l' prefix. Change-Id: Ib755673dfa9e71172bbef0a5aec075154c89a97b Signed-off-by: Arthur Heymans <arthur@aheymans.xyz> Reviewed-on: https://review.coreboot.org/c/coreboot/+/81675 Reviewed-by: Elyes Haouas <ehaouas@noos.fr> Reviewed-by: Felix Singer <service+coreboot-gerrit@felixsinger.de> Reviewed-by: Julius Werner <jwerner@chromium.org> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
184 lines
4.1 KiB
Text
184 lines
4.1 KiB
Text
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
|
|
#include <memlayout.h>
|
|
|
|
/* This file is included inside a SECTIONS block */
|
|
|
|
/* First we place the code and read only data (typically const declared).
|
|
* This could theoretically be placed in rom.
|
|
* The '.' in '.text . : {' is actually significant to prevent missing some
|
|
* SoC's entry points due to artificial alignment restrictions, see
|
|
* https://sourceware.org/binutils/docs/ld/Output-Section-Address.html
|
|
*/
|
|
|
|
/* Starting with version 18 LLVM the combination -ffunction-section -mcmodel=large
|
|
* puts code and data in '.ltext, '.lrodata', '.ldata' and '.lbss'
|
|
*/
|
|
|
|
.text . : {
|
|
_program = .;
|
|
_text = .;
|
|
#if !(ENV_X86 && ENV_BOOTBLOCK)
|
|
*(.init._start);
|
|
*(.init);
|
|
*(.init.*);
|
|
#endif
|
|
*(.text._start);
|
|
*(.text.stage_entry);
|
|
KEEP(*(.metadata_hash_anchor));
|
|
*(.text);
|
|
*(.text.*);
|
|
*(.ltext);
|
|
*(.ltext.*);
|
|
|
|
#if ENV_HAS_CBMEM
|
|
. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
|
|
_cbmem_init_hooks = .;
|
|
KEEP(*(.rodata.cbmem_init_hooks_early));
|
|
KEEP(*(.rodata.cbmem_init_hooks));
|
|
_ecbmem_init_hooks = .;
|
|
RECORD_SIZE(cbmem_init_hooks)
|
|
#endif
|
|
|
|
. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
|
|
_rsbe_init_begin = .;
|
|
KEEP(*(.rsbe_init));
|
|
_ersbe_init_begin = .;
|
|
RECORD_SIZE(rsbe_init_begin)
|
|
|
|
#if ENV_RAMSTAGE
|
|
. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
|
|
_pci_drivers = .;
|
|
KEEP(*(.rodata.pci_driver));
|
|
_epci_drivers = .;
|
|
RECORD_SIZE(pci_drivers)
|
|
. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
|
|
_cpu_drivers = .;
|
|
KEEP(*(.rodata.cpu_driver));
|
|
_ecpu_drivers = .;
|
|
RECORD_SIZE(cpu_drivers)
|
|
#endif
|
|
|
|
. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
|
|
*(.rodata);
|
|
*(.rodata.*);
|
|
*(.lrodata);
|
|
*(.lrodata.*);
|
|
. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
|
|
_etext = .;
|
|
RECORD_SIZE(text)
|
|
} : to_load
|
|
|
|
#if ENV_RAMSTAGE && (CONFIG(COVERAGE) || CONFIG(ASAN_IN_RAMSTAGE))
|
|
.ctors . : {
|
|
. = ALIGN(0x100);
|
|
__CTOR_LIST__ = .;
|
|
KEEP(*(.ctors));
|
|
LONG(0);
|
|
LONG(0);
|
|
__CTOR_END__ = .;
|
|
} : to_load
|
|
#endif
|
|
|
|
/* Include data, bss, and heap in that order. Not defined for all stages. */
|
|
#if !ENV_SEPARATE_DATA_AND_BSS
|
|
.data . : {
|
|
. = ALIGN(ARCH_CACHELINE_ALIGN_SIZE);
|
|
_data = .;
|
|
|
|
/*
|
|
* The postcar phase uses a stack value that is located in the relocatable
|
|
* module section. While the postcar stage could be linked like smm and
|
|
* other rmodules the postcar stage needs similar semantics of the more
|
|
* traditional stages in the coreboot infrastructure. Therefore it's easier
|
|
* to specialize this case.
|
|
*/
|
|
#if ENV_RMODULE || ENV_POSTCAR
|
|
_rmodule_params = .;
|
|
KEEP(*(.module_parameters));
|
|
_ermodule_params = .;
|
|
RECORD_SIZE(rmodule_params)
|
|
#endif
|
|
|
|
*(.data);
|
|
*(.data.*);
|
|
*(.ldata);
|
|
*(.ldata.*);
|
|
*(.sdata);
|
|
*(.sdata.*);
|
|
|
|
#if ENV_ROMSTAGE_OR_BEFORE
|
|
PROVIDE(_preram_cbmem_console = .);
|
|
PROVIDE(_epreram_cbmem_console = _preram_cbmem_console);
|
|
PROVIDE(_preram_cbmem_console_size = ABSOLUTE(0));
|
|
#elif ENV_RAMSTAGE
|
|
. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
|
|
_bs_init_begin = .;
|
|
KEEP(*(.bs_init));
|
|
LONG(0);
|
|
LONG(0);
|
|
_ebs_init_begin = .;
|
|
RECORD_SIZE(bs_init_begin)
|
|
#endif
|
|
|
|
. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
|
|
_edata = .;
|
|
RECORD_SIZE(data)
|
|
} : to_load
|
|
#endif
|
|
|
|
#if !ENV_SEPARATE_DATA_AND_BSS
|
|
.bss . (NOLOAD) : {
|
|
. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
|
|
_bss = .;
|
|
*(.bss)
|
|
*(.bss.*)
|
|
*(.lbss)
|
|
*(.lbss.*)
|
|
*(.sbss)
|
|
*(.sbss.*)
|
|
. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
|
|
_ebss = .;
|
|
RECORD_SIZE(bss)
|
|
} : to_load
|
|
#endif
|
|
|
|
#if ENV_HAS_HEAP_SECTION
|
|
.heap . (NOLOAD) : {
|
|
. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
|
|
_heap = .;
|
|
. += CONFIG_HEAP_SIZE;
|
|
. = ALIGN(ARCH_POINTER_ALIGN_SIZE);
|
|
_eheap = .;
|
|
RECORD_SIZE(heap)
|
|
} : to_load
|
|
#endif
|
|
|
|
#if ENV_RAMSTAGE && CONFIG(ASAN_IN_RAMSTAGE)
|
|
_shadow_size = (_eheap - _data) >> 3;
|
|
REGION(asan_shadow, ., _shadow_size, ARCH_POINTER_ALIGN_SIZE)
|
|
#endif
|
|
|
|
_eprogram = .;
|
|
RECORD_SIZE(program)
|
|
|
|
/* The stage cache drops CONFIG_HEAP_SIZE bytes from the end of the in-memory
|
|
image of the ramstage, so ensure that when moving that many bytes backwards
|
|
from the program end, we're in the heap (or later), in some region that
|
|
doesn't contain initialized code or data. */
|
|
#if ENV_RAMSTAGE
|
|
_bogus = ASSERT(_eprogram - CONFIG_HEAP_SIZE >= _heap,
|
|
"HEAP_SIZE and heap misaligned");
|
|
#endif
|
|
|
|
/* Discard the sections we don't need/want */
|
|
|
|
zeroptr = 0;
|
|
|
|
/DISCARD/ : {
|
|
*(.comment)
|
|
*(.comment.*)
|
|
*(.note)
|
|
*(.note.*)
|
|
*(.eh_frame);
|
|
}
|