/* # Developer notes
- Symbols that start with a double underscore (__) are considered "private"
- Symbols that start with a single underscore (_) are considered "semi-public"; they can be
overridden in a user linker script, but should not be referred from user code (e.g. `extern "C" {
static mut __sbss }`).
- `EXTERN` forces the linker to keep a symbol in the final binary. We use this to make sure a
symbol if not dropped if it appears in or near the front of the linker arguments and "it's not
needed" by any of the preceding objects (linker arguments)
- `PROVIDE` is used to provide default values that can be overridden by a user linker script
- On alignment: it's important for correctness that the VMA boundaries of both .bss and .data *and*
the LMA of .data are all 4-byte aligned. These alignments are assumed by the RAM initialization
routine. There's also a second benefit: 4-byte aligned boundaries means that you won't see
"Address (..) is out of bounds" in the disassembly produced by `objdump`.
*/
/* Provides information about the memory layout of the device */
/* This will be provided by the user (see `memory.x`) or by a Board Support Crate */
INCLUDE memory.x
/* # Entry point = reset vector */
ENTRY(Reset);
EXTERN(__RESET_VECTOR); /* depends on the `Reset` symbol */
/* # Exception vectors */
/* This is effectively weak aliasing at the linker level */
/* The user can override any of these aliases by defining the corresponding symbol themselves (cf.
the `exception!` macro) */
EXTERN(__EXCEPTIONS); /* depends on all the these PROVIDED symbols */
EXTERN(DefaultHandler);
PROVIDE(NonMaskableInt = DefaultHandler);
EXTERN(HardFault);
PROVIDE(MemoryManagement = DefaultHandler);
PROVIDE(BusFault = DefaultHandler);
PROVIDE(UsageFault = DefaultHandler);
PROVIDE(SecureFault = DefaultHandler);
PROVIDE(SVCall = DefaultHandler);
PROVIDE(DebugMonitor = DefaultHandler);
PROVIDE(PendSV = DefaultHandler);
PROVIDE(SysTick = DefaultHandler);
/* # Interrupt vectors */
EXTERN(__INTERRUPTS); /* `static` variable similar to `__EXCEPTIONS` */
/* # User overridable symbols I */
/* Lets the user place the stack in a different RAM region */
PROVIDE(_stack_start = ORIGIN(RAM) + LENGTH(RAM));
/* # Sections */
SECTIONS
{
/* ## Sections in FLASH */
/* ### Vector table */
.vector_table ORIGIN(FLASH) : ALIGN(4)
{
/* Initial Stack Pointer (SP) value */
__STACK_START = .; /* Just to get a nicer name in the disassembly */
LONG(_stack_start);
/* Reset vector */
KEEP(*(.vector_table.reset_vector)); /* this is `__RESET_VECTOR` symbol */
__reset_vector = ABSOLUTE(.);
/* Exceptions */
KEEP(*(.vector_table.exceptions)); /* this is `__EXCEPTIONS` symbol */
__eexceptions = ABSOLUTE(.);
/* Device specific interrupts */
KEEP(*(.vector_table.interrupts)); /* this is `__INTERRUPTS` symbol */
__einterrupts = ABSOLUTE(.);
} > FLASH
/* ### .text */
.text _stext :
{
*(.text .text.*);
__etext = ABSOLUTE(.);
} > FLASH
/* ### .rodata */
.rodata :
{
. = ALIGN(4); /* 4-byte align the start (VMA) of this section */
/* __srodata = ABSOLUTE(.); */
*(.rodata .rodata.*);
. = ALIGN(4); /* 4-byte align the end (VMA) of this section */
__erodata = ABSOLUTE(.);
} > FLASH
/* ## Sections in RAM */
/* ### .data */
.data : AT(__erodata) /* LMA */
{
. = ALIGN(4); /* 4-byte align the start (VMA) of this section */
__sdata = ABSOLUTE(.);
*(.data .data.*);
. = ALIGN(4); /* 4-byte align the end (VMA) of this section */
__edata = ABSOLUTE(.);
} > RAM
/* ### .bss */
.bss :
{
. = ALIGN(4); /* 4-byte align the start (VMA) of this section */
__sbss = ABSOLUTE(.);
*(.bss .bss.*);
. = ALIGN(4); /* 4-byte align the end (VMA) of this section */
__ebss = ABSOLUTE(.);
} > RAM
/* ## Fake output .got section */
/* Dynamic relocations are unsupported. This section is only used to detect relocatable code in
the input files and raise an error if relocatable code is found */
.got :
{
__sgot = ABSOLUTE(.);
KEEP(*(.got .got.*));
__egot = ABSOLUTE(.);
} > FLASH
/* ## Discarded sections */
/DISCARD/ :
{
/* Unused exception related info that only wastes space */
*(.ARM.exidx.*);
}
}
/* # User overridable symbols II */
/* (The user overridable symbols are split in two parts because LLD demands that the RHS of PROVIDE
to be defined before the PROVIDE invocation) */
/* Lets the user override this to place .text a bit further than the vector table. Required by
microcontrollers that store their configuration right after the vector table. */
PROVIDE(_stext = __einterrupts);
/* # Hardcoded symbols */
/* Place `.bss` at the start of the RAM region */
__sidata = LOADADDR(.data);
/* Place the heap right after `.bss` and `.data` */
__sheap = __ebss;
/* # Sanity checks */
/* Do not exceed this mark in the error messages below | */
ASSERT(__reset_vector == ORIGIN(FLASH) + 0x8, "
cortex-m-rt: The reset vector is missing. This is a bug in cortex-m-rt. Please file a bug
report at: https://github.com/japaric/cortex-m-rt/issues");
ASSERT(__eexceptions - ORIGIN(FLASH) == 0x40, "
cortex-m-rt: The exception vectors are missing. This is a bug in cortex-m-rt. Please file
a bug report at: https://github.com/japaric/cortex-m-rt/issues");
ASSERT(__sheap >= __ebss, "
cortex-m-rt: The heap overlaps with the .bss section. This is a bug in cortex-m-rt. Please
file a bug report at: https://github.com/japaric/cortex-m-rt/issues");
ASSERT(__sheap >= __edata, "
cortex-m-rt: The heap overlaps with the .data section. This is a bug in cortex-m-rt.
Please file a bug report at: https://github.com/japaric/cortex-m-rt/issues");
ASSERT(__einterrupts - __eexceptions > 0, "
cortex-m-rt: The interrupt vectors are missing. Possible solutions, from most likely to
less likely:
- Link to a device crate
- Disable the 'device' feature of cortex-m-rt to build a generic application (a dependency
may be enabling it)
- Supply the interrupt handlers yourself. Check the documentation for details.");
ASSERT(__einterrupts <= _stext, "
cortex-m-rt: The '.text' section can't be placed inside the '.vector_table' section. Set
'_stext' to an address greater than '__einterrupts' (cf. `nm` output)");
ASSERT(_stext < ORIGIN(FLASH) + LENGTH(FLASH), "
cortex-m-rt The '.text' section must be placed inside the FLASH memory. Set '_stext' to an
address smaller than 'ORIGIN(FLASH) + LENGTH(FLASH)");
/* This has been temporarily omitted because it's not supported by LLD */
/* ASSERT(__sbss % 4 == 0 && __ebss % 4 == 0, " */
/* .bss is not 4-byte aligned at its boundaries. This is a cortex-m-rt bug."); */
/* ASSERT(__sdata % 4 == 0 && __edata % 4 == 0, " */
/* .data is not 4-byte aligned at its boundaries. This is a cortex-m-rt bug."); */
/* ASSERT(__sidata % 4 == 0, " */
/* __sidata is not 4-byte aligned. This is a cortex-m-rt bug."); */
ASSERT(__sgot == __egot, "
.got section detected in the input object files. Dynamic relocations are not supported.
If you are linking to C code compiled using the `cc` crate then modify your build script
to compile the C code _without_ the -fPIC flag. See the documentation of the
`cc::Build.pic` method for details.");
/* Do not exceed this mark in the error messages above | */