# Copyright (C) 2014-2024 Free Software Foundation, Inc.
#
# Copying and distribution of this file, with or without modification,
# are permitted in any medium without royalty provided the copyright
# notice and this notice are preserved.
#
# Unusual variables checked by this code:
# NOP - four byte opcode for no-op (defaults to 0)
# DATA_ADDR - if end-of-text-plus-one-page isn't right for data start
# OTHER_READWRITE_SECTIONS - other than .data .bss .ctors .sdata ...
# (e.g., .PARISC.global)
# OTHER_SECTIONS - at the end
# EXECUTABLE_SYMBOLS - symbols that must be defined for an
# executable (e.g., _DYNAMIC_LINK)
# TEXT_START_SYMBOLS - symbols that appear at the start of the
# .text section.
# DATA_START_SYMBOLS - symbols that appear at the start of the
# .data section.
# OTHER_BSS_SYMBOLS - symbols that appear at the start of the
# .bss section besides __bss_start.
# EMBEDDED - whether this is for an embedded system.
#
# When adding sections, do note that the names of some sections are used
# when specifying the start address of the next.
#
test -z "$ENTRY" && ENTRY=_start
test -z "${BIG_OUTPUT_FORMAT}" && BIG_OUTPUT_FORMAT=${OUTPUT_FORMAT}
test -z "${LITTLE_OUTPUT_FORMAT}" && LITTLE_OUTPUT_FORMAT=${OUTPUT_FORMAT}
if [ -z "$MACHINE" ]; then OUTPUT_ARCH=${ARCH}; else OUTPUT_ARCH=${ARCH}:${MACHINE}; fi
test "$LD_FLAG" = "N" && DATA_ADDR=.
CTOR=".ctors ${CONSTRUCTING-0} :
{
${CONSTRUCTING+ PROVIDE (__CTOR_LIST__ = .); }
${CONSTRUCTING+${CTOR_START}}
KEEP (*(.ctors))
${CONSTRUCTING+${CTOR_END}}
${CONSTRUCTING+ PROVIDE(__CTOR_END__ = .); }
} ${RELOCATING+ > ${TEXT_MEMORY}}"
DTOR=" .dtors ${CONSTRUCTING-0} :
{
${CONSTRUCTING+ PROVIDE(__DTOR_LIST__ = .); }
KEEP (*(.dtors))
${CONSTRUCTING+ PROVIDE(__DTOR_END__ = .); }
} ${RELOCATING+ > ${TEXT_MEMORY}}"
VECTORS="
/* If the 'vectors_addr' symbol is defined, it indicates the start address
of interrupt vectors.
In general, the vectors address is 0xfffe00. This can be overriden
with the '-defsym vectors_addr=0xbfc000' ld option. If you do this,
then your startup code should also set the IVBR register accordingly.
*/
PROVIDE (_vectors_addr = DEFINED (vectors_addr) ? vectors_addr : 0xfffe00);
.vectors DEFINED (vectors_addr) ? vectors_addr : 0xfffe00 :
{
KEEP (*(.vectors))
}"
#
# We provide two emulations: a fixed on that defines some memory banks
# and a configurable one that includes a user provided memory definition.
#
case $GENERIC_BOARD in
yes|1|YES)
MEMORY_DEF="
/* Get memory banks definition from some user configuration file.
This file must be located in some linker directory (search path
with -L
). See fixed memory banks emulation script. */
INCLUDE memory.x;
"
;;
*)
MEMORY_DEF="
/* Fixed definition of the available memory banks.
See generic emulation script for a user defined configuration. */
MEMORY
{
text (rx) : ORIGIN = $[$ROM_TOP - $ROM_SIZE + 1], LENGTH = ${ROM_SIZE} - 4
data : ORIGIN = ${RAM_START_ADDR}, LENGTH = ${RAM_SIZE}
eeprom : ORIGIN = ${EEPROM_START_ADDR}, LENGTH = ${EEPROM_SIZE}
rvec : ORIGIN = 0xFFFFFC, LENGTH = 4
}
/* Setup the stack on the top of the data memory bank. */
PROVIDE (_stack = ${RAM_START_ADDR} + ${RAM_SIZE} - 1);
"
;;
esac
STARTUP_CODE="
/* Startup code. */
KEEP (*(.install0)) /* Section should setup the stack pointer. */
KEEP (*(.install1)) /* Place holder for applications. */
KEEP (*(.install2)) /* Optional installation of data sections in RAM. */
KEEP (*(.install3)) /* Place holder for applications. */
KEEP (*(.install4)) /* Section that calls the main. */
"
FINISH_CODE="
/* Finish code. */
KEEP (*(.fini0)) /* Beginning of finish code (_exit symbol). */
KEEP (*(.fini1)) /* Place holder for applications. */
KEEP (*(.fini2)) /* C++ destructors. */
KEEP (*(.fini3)) /* Place holder for applications. */
KEEP (*(.fini4)) /* Runtime exit. */
"
PRE_COMPUTE_DATA_SIZE="
/* SCz: this does not work yet... This is supposed to force the loading
of _map_data.o (from libgcc.a) when the .data section is not empty.
By doing so, this should bring the code that copies the .data section
from ROM to RAM at init time.
___pre_comp_data_size = SIZEOF(.data);
__install_data_sections = ___pre_comp_data_size > 0 ?
__map_data_sections : 0;
*/
"
INSTALL_RELOC="
.install0 0 : { *(.install0) }
.install1 0 : { *(.install1) }
.install2 0 : { *(.install2) }
.install3 0 : { *(.install3) }
.install4 0 : { *(.install4) }
"
FINISH_RELOC="
.fini0 0 : { *(.fini0) }
.fini1 0 : { *(.fini1) }
.fini2 0 : { *(.fini2) }
.fini3 0 : { *(.fini3) }
.fini4 0 : { *(.fini4) }
"
BSS_DATA_RELOC="
.data1 0 : { *(.data1) }
/* We want the small data sections together, so single-instruction offsets
can access them all, and initialized data all before uninitialized, so
we can shorten the on-disk segment size. */
.sdata 0 : { *(.sdata) }
.sbss 0 : { *(.sbss) }
.scommon 0 : { *(.scommon) }
"
SOFT_REGS_RELOC="
.softregs 0 : { *(.softregs) }
"
cat < ${TEXT_MEMORY}}
.init ${RELOCATING-0} :
{
KEEP (*(SORT_NONE(.init)))
} ${RELOCATING+=${NOP-0}}
${RELOCATING-${INSTALL_RELOC}}
${RELOCATING-${FINISH_RELOC}}
.text ${RELOCATING-0}:
{
/* Put startup code at beginning so that _start keeps same address. */
${RELOCATING+${STARTUP_CODE}}
*(.text)
${RELOCATING+*(.text.*)}
/* .gnu.warning sections are handled specially by elf.em. */
*(.gnu.warning)
${RELOCATING+*(.gnu.linkonce.t.*)}
${RELOCATING+*(.tramp)}
${RELOCATING+*(.tramp.*)}
${RELOCATING+KEEP (*(SORT_NONE(.fini)))}
${RELOCATING+${FINISH_CODE}}
${RELOCATING+_etext = .;}
${RELOCATING+PROVIDE (etext = .);}
${RELOCATING+. = ALIGN(2);}
} ${RELOCATING+ > ${TEXT_MEMORY} =${NOP}}
.rvec ${RELOCATING-0} :
{
${RELOCATING+LONG(_start);}
} ${RELOCATING+ > rvec}
.eh_frame ${RELOCATING-0} :
{
KEEP (*(.eh_frame))
} ${RELOCATING+ > ${TEXT_MEMORY}}
.gcc_except_table ${RELOCATING-0} :
{
*(.gcc_except_table)
} ${RELOCATING+ > ${TEXT_MEMORY}}
.rodata ${RELOCATING-0} :
{
*(.rodata)
${RELOCATING+*(.rodata.*)}
${RELOCATING+*(.gnu.linkonce.r*)}
${RELOCATING+. = ALIGN(2);}
} ${RELOCATING+ > ${TEXT_MEMORY} =0xffffffff}
.rodata1 ${RELOCATING-0} :
{
*(.rodata1)
${RELOCATING+. = ALIGN(2);}
} ${RELOCATING+ > ${TEXT_MEMORY} =0xffffffff}
/* Constructor and destructor tables are in ROM. */
${RELOCATING+${CTOR}}
${RELOCATING+${DTOR}}
.jcr ${RELOCATING-0} :
{
KEEP (*(.jcr))
} ${RELOCATING+ > ${TEXT_MEMORY}}
/* Start of the data section image in ROM. */
${RELOCATING+__data_image = .;}
${RELOCATING+PROVIDE (__data_image = .);}
/* All read-only sections that normally go in PROM must be above.
We construct the DATA image section in PROM at end of all these
read-only sections. The data image must be copied at init time.
Refer to GNU ld, Section 3.6.8.2 Output Section LMA. */
.data ${RELOCATING-0} : ${RELOCATING+AT (__data_image)}
{
${RELOCATING+__data_section_start = .;}
${RELOCATING+PROVIDE (__data_section_start = .);}
${RELOCATING+${DATA_START_SYMBOLS}}
${RELOCATING+*(.sdata)}
*(.data)
${RELOCATING+*(.data.*)}
${RELOCATING+*(.data1)}
${RELOCATING+*(.gnu.linkonce.d.*)}
${CONSTRUCTING+CONSTRUCTORS}
${RELOCATING+_edata = .;}
${RELOCATING+PROVIDE (edata = .);}
${RELOCATING+. = ALIGN(2);}
} ${RELOCATING+ > ${DATA_MEMORY} =0xffffffff}
${RELOCATING+__data_section_size = SIZEOF(.data);}
${RELOCATING+PROVIDE (__data_section_size = SIZEOF(.data));}
${RELOCATING+__data_image_end = __data_image + __data_section_size;}
${RELOCATING+${PRE_COMPUTE_DATA_SIZE}}
.install ${RELOCATING-0}:
{
${RELOCATING+. = __data_section_size;}
} ${RELOCATING+ > ${TEXT_MEMORY}}
/* Relocation for some bss and data sections. */
${RELOCATING-${BSS_DATA_RELOC}}
${RELOCATING-${SOFT_REGS_RELOC}}
.bss ${RELOCATING-0} :
{
${RELOCATING+__bss_start = .;}
${RELOCATING+*(.softregs)}
${RELOCATING+*(.sbss)}
${RELOCATING+*(.common)}
${RELOCATING+*(.scommon)}
${RELOCATING+*(.dynbss)}
*(.bss)
${RELOCATING+*(.bss.*)}
${RELOCATING+*(.gnu.linkonce.b.*)}
${RELOCATING+*(COMMON)}
${RELOCATING+PROVIDE (_end = .);}
} ${RELOCATING+ > ${DATA_MEMORY}}
${RELOCATING+__bss_size = SIZEOF(.bss);}
${RELOCATING+PROVIDE (__bss_size = SIZEOF(.bss));}
.eeprom ${RELOCATING-0} :
{
*(.eeprom)
${RELOCATING+*(.eeprom.*)}
} ${RELOCATING+ > ${EEPROM_MEMORY}}
${RELOCATING+${VECTORS}}
EOF
source_sh $srcdir/scripttempl/misc-sections.sc
cat <