userland: simplify linker script

userland: simplify linker script

/* Userland Generic Layout
 *
 * This linker script is designed for Tock apps where the end microcontroller
 * is not known. Therefore, this script over provisions space on some platforms.
 */

/* Memory Spaces Definitions, 448K flash, 64K ram */
PROG_LENGTH = 0x00040000;
RAM_LENGTH  = 0x00010000;

ENTRY(_start)

/* Note: Because apps are relocated, the FLASH address here acts as a sentinel
 * value for relocation fixup routines. The application loader will select the
 * actual location in flash where the app is placed.
 */
MEMORY {
    FLASH (rx) : ORIGIN = 0x80000000, LENGTH = PROG_LENGTH
    SRAM (RWX) : ORIGIN = 0x00000000, LENGTH = RAM_LENGTH
}

SECTIONS {
    /* App state section. Used for persistent app data.
     * We put this first so that if the app code changes but the persistent
     * data doesn't, the app_state can be preserved.
     */
    .app_state :
    {
        KEEP (*(.app_state))
        . = ALIGN(4); /* Make sure we're word-aligned here */
    } > FLASH =0xFF

    /* Text section, Code! */
    .text :
    {
        _text = .;
        /**
         * Populate the header expected by `crt0`:
         *
         *  struct hdr {
         *    uint32_t got_sym_start;
         *    uint32_t got_start;
         *    uint32_t got_size;
         *    uint32_t data_sym_start;
         *    uint32_t data_start;
         *    uint32_t data_size;
         *    uint32_t bss_start;
         *    uint32_t bss_size;
         *    uint32_t reldata_start;
         *    uint32_t stack_size;
         *  };
         */
        /* Offset of GOT symbols in flash */
        LONG(LOADADDR(.got) - _text);
        /* Offset of GOT section in memory */
        LONG(_got);
        /* Size of GOT section */
        LONG(SIZEOF(.got));
        /* Offset of data symbols in flash */
        LONG(LOADADDR(.data) - _text);
        /* Offset of data section in memory */
        LONG(_data);
        /* Size of data section */
        LONG(SIZEOF(.data));
        /* Offset of BSS section in memory */
        LONG(_bss);
        /* Size of BSS section */
        LONG(SIZEOF(.bss));
        /* First address offset after program flash, where elf2tab places
         * .rel.data section */
        LONG(LOADADDR(.endflash) - _text);
         /* The size of the stack requested by this application */
        LONG(STACK_SIZE);

        KEEP (*(.start))
        *(.text*)
        *(.rodata*)
        KEEP (*(.syscalls))
        _etext = .;
        *(.ARM.extab*)
        . = ALIGN(4); /* Make sure we're word-aligned here */
    } > FLASH =0xFF

    /* Global Offset Table */
    .got :
    {
        . = ALIGN(4); /* Make sure we're word-aligned here */
        _got = .;
        *(.got*)
        *(.got.plt*)
    } > SRAM AT > FLASH

    /* Data section, static initialized variables
     *  Note: This is placed in Flash after the text section, but needs to be
     *  moved to SRAM at runtime
     */
    .data :
    {
        . = ALIGN(4); /* Make sure we're word-aligned here */
        _data = .;
        KEEP(*(.data*))
    } > SRAM AT > FLASH

    /* BSS section, static uninitialized variables */
    .bss :
    {
        . = ALIGN(4); /* Make sure we're word-aligned here */
        _bss = .;
        KEEP(*(.bss*))
        *(COMMON)
    } > SRAM

    /* End of flash. */
    .endflash :
    {
    } > FLASH

    /* ARM Exception support
     *
     * This contains compiler-generated support for unwinding the stack,
     * consisting of key-value pairs of function addresses and information on
     * how to unwind stack frames.
     * https://wiki.linaro.org/KenWerner/Sandbox/libunwind?action=AttachFile&do=get&target=libunwind-LDS.pdf
     *
     * .ARM.exidx is sorted, so has to go in its own output section.
     *
     * __NOTE__: It's at the end because we currently don't actually serialize
     * it to the binary in elf2tbf. If it was before the RAM sections, it would
     * through off our calculations of the header.
     */
    PROVIDE_HIDDEN (__exidx_start = .);
    .ARM.exidx :
    {
      /* (C++) Index entries for section unwinding */
      *(.ARM.exidx* .gnu.linkonce.armexidx.*)
    } > FLASH
    PROVIDE_HIDDEN (__exidx_end = .);
}

/* Userland Generic Layout
 *
 * This linker script is designed for Tock apps where the end microcontroller
 * is not known. Therefore, this script over provisions space on some platforms.
 */

/* Memory Spaces Definitions, 448K flash, 64K ram */
PROG_LENGTH = 0x00040000;
RAM_LENGTH  = 0x00010000;

ENTRY(_start)

/* Note: Because apps are relocated, the FLASH address here acts as a sentinel
 * value for relocation fixup routines. The application loader will select the
 * actual location in flash where the app is placed.
 */
MEMORY {
    FLASH (rx) : ORIGIN = 0x80000000, LENGTH = PROG_LENGTH
    SRAM (RWX) : ORIGIN = 0x00000000, LENGTH = RAM_LENGTH
}

SECTIONS {
    /* Text section, Code! */
    .text :
    {
        _text = .;
        /**
         * Populate the header expected by `crt0`:
         *
         *
         *  struct hdr {
         *    uint32_t got_sym_start;
         *    uint32_t got_start;
         *    uint32_t got_size;
         *    uint32_t data_sym_start;
         *    uint32_t data_start;
         *    uint32_t data_size;
         *    uint32_t bss_start;
         *    uint32_t bss_size;
         *    uint32_t reldata_start;
         *  };
         */
        /* Offset of GOT symbols in flash */
        LONG(LOADADDR(.got) - _text);
        /* Offset of GOT section in memory */
        LONG(_got);
        /* Size of GOT section */
        LONG(SIZEOF(.got));
        /* Offset of data symbols in flash */
        LONG(LOADADDR(.data) - _text);
        /* Offset of data section in memory */
        LONG(_data);
        /* Size of data section */
        LONG(SIZEOF(.data));
        /* Offset of BSS section in memory */
        LONG(_bss);
        /* Size of BSS section */
        LONG(SIZEOF(.bss));
        /* First address offset after program flash, where elf2tbf places
         * .rel.data section */
        LONG(LOADADDR(.endsec) - _text);
         /* The size of the stack requested by this application */
        LONG(STACK_SIZE);

        KEEP (*(.start))
        *(.text*)
        *(.rodata*)
        KEEP (*(.syscalls))
        _etext = .;
        *(.ARM.extab*)
        . = ALIGN(4); /* Make sure we're word-aligned here */
    } > FLASH =0xFF

    /* App state section. Used for persistent app data. */
    .app_state :
    {
        KEEP (*(.app_state))
        . = ALIGN(4); /* Make sure we're word-aligned here */
    } > FLASH =0xFF

    /* Global Offset Table */
    .got :
    {
        _got = .;
        *(.got*)
        *(.got.plt*)
        . = ALIGN(4); /* Make sure we're word-aligned here */
    } > SRAM AT > FLASH

    /* Data section, static initialized variables
     *  Note: This is placed in Flash after the text section, but needs to be
     *  moved to SRAM at runtime
     */
    .data :
    {
        _data = .;
        KEEP(*(.data*))
        . = ALIGN(4); /* Make sure we're word-aligned here */
    } > SRAM AT > FLASH

    /* BSS section, static uninitialized variables */
    .bss :
    {
        _bss = .;
        KEEP(*(.bss*))
        *(COMMON)
        . = ALIGN(4); /* Make sure we're word-aligned here */
    } > SRAM

    /*
     * __NOTE__: The following symbols are used only to hint to elf2tbf how much
     * total memory to request from the OS.
     */
    .stack :
    {
        . += STACK_SIZE;
        . = ALIGN(4); /* Make sure we're word-aligned here */
    } > SRAM

    .app_heap :
    {
        . += APP_HEAP_SIZE;
        . = ALIGN(4); /* Make sure we're word-aligned here */
    } > SRAM

    .kernel_heap :
    {
        . += KERNEL_HEAP_SIZE;
        . = ALIGN(4); /* Make sure we're word-aligned here */
    } > SRAM

    _sram_end = .;
    .endsec :
    {
    } > FLASH

    /* ARM Exception support
     *
     * This contains compiler-generated support for unwinding the stack,
     * consisting of key-value pairs of function addresses and information on
     * how to unwind stack frames.
     * https://wiki.linaro.org/KenWerner/Sandbox/libunwind?action=AttachFile&do=get&target=libunwind-LDS.pdf
     *
     * .ARM.exidx is sorted, so has to go in its own output section.
     *
     * __NOTE__: It's at the end because we currently don't actually serialize
     * it to the binary in elf2tbf. If it was before the RAM sections, it would
     * through off our calculations of the header.
     */
    PROVIDE_HIDDEN (__exidx_start = .);
    .ARM.exidx :
    {
      /* (C++) Index entries for section unwinding */
      *(.ARM.exidx* .gnu.linkonce.armexidx.*)
    } > FLASH
    PROVIDE_HIDDEN (__exidx_end = .);

}


boards: opentitan: Update the SRAM layout

As Tock for OT has gotten larger the SRAM allocated for apps has moved
up in memory. Let's update the linker script to better match what Tock
is allocating.

Signed-off-by: Alistair Francis <52ecf00b70a50079ae8d5fa09b9af6904950b63c@wdc.com>

/* Layout for the RISC-V 32 boards, used by the examples in this repository. */

MEMORY {
  /*
   * The TBF header can change in size so use 0x40 combined with
   * --protected-region-size with elf2tab to cover a header upto that
   * size.
   *
   * Note that the SRAM address may need to be changed depending on
   * the kernel binary, check for the actual address of APP_MEMORY!
   */
  FLASH (rx) : ORIGIN = 0x20030040, LENGTH = 32M
  SRAM (rwx) : ORIGIN = 0x10002D00, LENGTH = 512K
}

/*
 * Any change to STACK_SIZE should be accompanied by a corresponding change to
 * `elf2tab`'s `--stack` option
 */
STACK_SIZE = 2048;

MPU_MIN_ALIGN = 1K;

INCLUDE layout_generic.ld

/* Layout for the RISC-V 32 boards, used by the examples in this repository. */

MEMORY {
  /*
   * The TBF header can change in size so use 0x40 combined with
   * --protected-region-size with elf2tab to cover a header upto that
   * size.
   *
   * Note that the SRAM address may need to be changed depending on
   * the kernel binary, check for the actual address of APP_MEMORY!
   */
  FLASH (rx) : ORIGIN = 0x20030040, LENGTH = 32M
  SRAM (rwx) : ORIGIN = 0x10002800, LENGTH = 512K
}

/*
 * Any change to STACK_SIZE should be accompanied by a corresponding change to
 * `elf2tab`'s `--stack` option
 */
STACK_SIZE = 2048;

MPU_MIN_ALIGN = 1K;

INCLUDE layout_generic.ld


Sections updated

Sections updated

/*
  Copyright (c) 2014-2015 Arduino LLC.  All right reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the GNU Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

/* Linker script to configure memory regions.
 * Need modifying for a specific board.
 *   FLASH.ORIGIN: starting address of flash
 *   FLASH.LENGTH: length of flash
 *   RAM.ORIGIN: starting address of RAM bank 0
 *   RAM.LENGTH: length of RAM bank 0
 */
MEMORY
{
  FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00002000 /*Put here if necesary bootloader start addressing*/
  RAM (rwx) : ORIGIN = 0x00010000, LENGTH = 0x00001000
}

/* Linker script to place sections and symbol values. Should be used together
 * with other linker script that defines memory regions FLASH and RAM.
 * It references following symbols, which must be defined in code:
 *   Reset_Handler : Entry of reset handler
 *
 * It defines following symbols, which code can use without definition:
 *   __exidx_start
 *   __exidx_end
 *   __copy_table_start__
 *   __copy_table_end__
 *   __zero_table_start__
 *   __zero_table_end__
 *   __etext
 *   __data_start__
 *   __preinit_array_start
 *   __preinit_array_end
 *   __init_array_start
 *   __init_array_end
 *   __fini_array_start
 *   __fini_array_end
 *   __data_end__
 *   __bss_start__
 *   __bss_end__
 *   __end__
 *   end
 *   __HeapLimit
 *   __StackLimit
 *   __StackTop
 *   __stack
 */
ENTRY(Reset_Handler)

SECTIONS
{
	.text :
	{
		KEEP(*(.isr_vector))
		*(.text*)

		KEEP(*(.init))
		KEEP(*(.fini))

		/* .ctors */
		*crtbegin.o(.ctors)
		*crtbegin?.o(.ctors)
		*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
		*(SORT(.ctors.*))
		*(.ctors)

		/* .dtors */
 		*crtbegin.o(.dtors)
 		*crtbegin?.o(.dtors)
 		*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
 		*(SORT(.dtors.*))
 		*(.dtors)

		*(.rodata*)

		KEEP(*(.eh_frame*))
	} > FLASH

	/** TODO: maybe this is necesary if there is a section called by this.*/
	/*.ARM.extab :
	{
		*(.ARM.extab* .gnu.linkonce.armextab.*)
	} > FLASH

	__exidx_start = .;
	.ARM.exidx :
	{
		*(.ARM.exidx* .gnu.linkonce.armexidx.*)
	} > FLASH
	__exidx_end = .;*/

	/* To copy multiple ROM to RAM sections,
	 * uncomment .copy.table section and,
	 * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */
	/*
	.copy.table :
	{
		. = ALIGN(4);
		__copy_table_start__ = .;
		LONG (__etext)
		LONG (__data_start__)
		LONG (__data_end__ - __data_start__)
		LONG (__etext2)
		LONG (__data2_start__)
		LONG (__data2_end__ - __data2_start__)
		__copy_table_end__ = .;
	} > FLASH
	*/

	/* To clear multiple BSS sections,
	 * uncomment .zero.table section and,
	 * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */
	/*
	.zero.table :
	{
		. = ALIGN(4);
		__zero_table_start__ = .;
		LONG (__bss_start__)
		LONG (__bss_end__ - __bss_start__)
		LONG (__bss2_start__)
		LONG (__bss2_end__ - __bss2_start__)
		__zero_table_end__ = .;
	} > FLASH
	*/

	__etext = .;

	.data : AT (__etext)
	{
		__data_start__ = .;
		*(vtable)
		*(.data*)

		. = ALIGN(4);
		/* preinit data */
		PROVIDE_HIDDEN (__preinit_array_start = .);
		KEEP(*(.preinit_array))
		PROVIDE_HIDDEN (__preinit_array_end = .);

		. = ALIGN(4);
		/* init data */
		PROVIDE_HIDDEN (__init_array_start = .);
		KEEP(*(SORT(.init_array.*)))
		KEEP(*(.init_array))
		PROVIDE_HIDDEN (__init_array_end = .);

		. = ALIGN(4);
		/* finit data */
		PROVIDE_HIDDEN (__fini_array_start = .);
		KEEP(*(SORT(.fini_array.*)))
		KEEP(*(.fini_array))
		PROVIDE_HIDDEN (__fini_array_end = .);

		KEEP(*(.jcr*))
		. = ALIGN(4);
		/* All data end */
		__data_end__ = .;

	} > RAM

	.bss :
	{
		. = ALIGN(4);
		__bss_start__ = .;
		*(.bss*)
		*(COMMON)
		. = ALIGN(4);
		__bss_end__ = .;
	} > RAM

	.heap (COPY):
	{
		__end__ = .;
		PROVIDE(end = .);
		*(.heap*)
		__HeapLimit = .;
	} > RAM

	/* .stack_dummy section doesn't contains any symbols. It is only
	 * used for linker to calculate size of stack sections, and assign
	 * values to stack symbols later */
	.stack_dummy (COPY):
	{
		*(.stack*)
	} > RAM

	/* Set stack top to end of RAM, and stack limit move down by
	 * size of stack_dummy section */
	__StackTop = ORIGIN(RAM) + LENGTH(RAM);
	__StackLimit = __StackTop - SIZEOF(.stack_dummy);
	PROVIDE(__stack = __StackTop);

	__ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ;

	/* Check if data + heap + stack exceeds RAM limit */
	ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
}

/*
  Copyright (c) 2014-2015 Arduino LLC.  All right reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the GNU Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

/* Linker script to configure memory regions.
 * Need modifying for a specific board.
 *   FLASH.ORIGIN: starting address of flash
 *   FLASH.LENGTH: length of flash
 *   RAM.ORIGIN: starting address of RAM bank 0
 *   RAM.LENGTH: length of RAM bank 0
 */
MEMORY
{
  FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x01000000 /*Put here if necesary bootloader start addressing*/
  RAM (rwx) : ORIGIN = 0x80000000, LENGTH = 0x80000000
}

/* Linker script to place sections and symbol values. Should be used together
 * with other linker script that defines memory regions FLASH and RAM.
 * It references following symbols, which must be defined in code:
 *   Reset_Handler : Entry of reset handler
 *
 * It defines following symbols, which code can use without definition:
 *   __exidx_start
 *   __exidx_end
 *   __copy_table_start__
 *   __copy_table_end__
 *   __zero_table_start__
 *   __zero_table_end__
 *   __etext
 *   __data_start__
 *   __preinit_array_start
 *   __preinit_array_end
 *   __init_array_start
 *   __init_array_end
 *   __fini_array_start
 *   __fini_array_end
 *   __data_end__
 *   __bss_start__
 *   __bss_end__
 *   __end__
 *   end
 *   __HeapLimit
 *   __StackLimit
 *   __StackTop
 *   __stack
 */
ENTRY(Reset_Handler)

SECTIONS
{
	.text :
	{
		KEEP(*(.isr_vector))
		*(.text*)

		KEEP(*(.init))
		KEEP(*(.fini))

		/* .ctors */
		*crtbegin.o(.ctors)
		*crtbegin?.o(.ctors)
		*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
		*(SORT(.ctors.*))
		*(.ctors)

		/* .dtors */
 		*crtbegin.o(.dtors)
 		*crtbegin?.o(.dtors)
 		*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
 		*(SORT(.dtors.*))
 		*(.dtors)

		*(.rodata*)

		KEEP(*(.eh_frame*))
	} > FLASH

	/** TODO: maybe this is necesary if there is a section called by this.*/
	/*.ARM.extab :
	{
		*(.ARM.extab* .gnu.linkonce.armextab.*)
	} > FLASH

	__exidx_start = .;
	.ARM.exidx :
	{
		*(.ARM.exidx* .gnu.linkonce.armexidx.*)
	} > FLASH
	__exidx_end = .;*/

	/* To copy multiple ROM to RAM sections,
	 * uncomment .copy.table section and,
	 * define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */
	/*
	.copy.table :
	{
		. = ALIGN(4);
		__copy_table_start__ = .;
		LONG (__etext)
		LONG (__data_start__)
		LONG (__data_end__ - __data_start__)
		LONG (__etext2)
		LONG (__data2_start__)
		LONG (__data2_end__ - __data2_start__)
		__copy_table_end__ = .;
	} > FLASH
	*/

	/* To clear multiple BSS sections,
	 * uncomment .zero.table section and,
	 * define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */
	/*
	.zero.table :
	{
		. = ALIGN(4);
		__zero_table_start__ = .;
		LONG (__bss_start__)
		LONG (__bss_end__ - __bss_start__)
		LONG (__bss2_start__)
		LONG (__bss2_end__ - __bss2_start__)
		__zero_table_end__ = .;
	} > FLASH
	*/

	__etext = .;

	.data : AT (__etext)
	{
		__data_start__ = .;
		*(vtable)
		*(.data*)

		. = ALIGN(4);
		/* preinit data */
		PROVIDE_HIDDEN (__preinit_array_start = .);
		KEEP(*(.preinit_array))
		PROVIDE_HIDDEN (__preinit_array_end = .);

		. = ALIGN(4);
		/* init data */
		PROVIDE_HIDDEN (__init_array_start = .);
		KEEP(*(SORT(.init_array.*)))
		KEEP(*(.init_array))
		PROVIDE_HIDDEN (__init_array_end = .);

		. = ALIGN(4);
		/* finit data */
		PROVIDE_HIDDEN (__fini_array_start = .);
		KEEP(*(SORT(.fini_array.*)))
		KEEP(*(.fini_array))
		PROVIDE_HIDDEN (__fini_array_end = .);

		KEEP(*(.jcr*))
		. = ALIGN(4);
		/* All data end */
		__data_end__ = .;

	} > RAM

	.bss :
	{
		. = ALIGN(4);
		__bss_start__ = .;
		*(.bss*)
		*(COMMON)
		. = ALIGN(4);
		__bss_end__ = .;
	} > RAM

	.heap (COPY):
	{
		__end__ = .;
		PROVIDE(end = .);
		*(.heap*)
		__HeapLimit = .;
	} > RAM

	/* .stack_dummy section doesn't contains any symbols. It is only
	 * used for linker to calculate size of stack sections, and assign
	 * values to stack symbols later */
	.stack_dummy (COPY):
	{
		*(.stack*)
	} > RAM

	/* Set stack top to end of RAM, and stack limit move down by
	 * size of stack_dummy section */
	__StackTop = ORIGIN(RAM) + LENGTH(RAM);
	__StackLimit = __StackTop - SIZEOF(.stack_dummy);
	PROVIDE(__stack = __StackTop);

	__ram_end__ = ORIGIN(RAM) + LENGTH(RAM) -1 ;

	/* Check if data + heap + stack exceeds RAM limit */
	ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
}


ld script fix

ld script fix

/**
    @copyright  Copyright (C) 2011 Oleg Kertanov <okertanov@gmail.com>
    @license    BSD
*/

/*OUTPUT_FORMAT("elf32-i386")*/

ENTRY (start)

SECTIONS
{
    . = 0x00100000;

    __image_start__ = . ;

    .text ALIGN (0x1000) :
    {
        __text_start__ = . ;
        *(.text)
        __text_end__ = . ;
    }

    __xen_guest ALIGN (0x1000) :
    {
        __xen_guest_start__ = . ;
        *(__xen_guest)
        __xen_guest_end__ = . ;
    }

    . = 0x00104000;

    .xen_shared_info ALIGN (0x4000) :
    {
        __xen_shared_info_start__ = . ;
        *(.xen_shared_info)
        __xen_shared_info_end__ = . ;
    }

    . = 0x00108000;

    .xen_hypercall_page ALIGN (0x4000) :
    {
        __xen_hypercall_page_start__ = . ;
        *(.xen_hypercall_page)
        __xen_hypercall_page_end__ = . ;
    }

    .rodata ALIGN (0x1000) :
    {
        __rodata_start__ = . ;
        *(.rodata)
        *(.rdata)
         __rodata_end__ = . ;
    }

    .data ALIGN (0x1000) :
    {
        __data_start__ = . ;
        *(.data)
        __data_end__ = . ;
    }

    .note ALIGN (0x1000) :
    {
        __note_start__ = . ;
        *(.note.*)
        __note_end__ = . ;
    }

    .bss ALIGN (0x1000) :
    {
        __bss_start__ = . ;
        *(COMMON)
        *(.bss)
        __bss_end__ = . ;
    }

    .end ALIGN (0x1000) :
    {
        __image_end__ = . ;
    }
}

/**
    @copyright  Copyright (C) 2011 Oleg Kertanov <okertanov@gmail.com>
    @license    BSD
*/

/*OUTPUT_FORMAT("elf32-i386")*/

ENTRY (start)

SECTIONS
{
    . = 0x00100000;

    __image_start__ = . ;

    .text 0x00100000 ALIGN (0x1000) :
    {
        __text_start__ = . ;
        *(.text)
        __text_end__ = . ;
    }

    __xen_guest ALIGN (0x1000) :
    {
        __xen_guest_start__ = . ;
        *(__xen_guest)
        __xen_guest_end__ = . ;
    }

    .xen_shared_info 0x00104000 ALIGN (0x4000) :
    {
        __xen_shared_info_start__ = . ;
        *(.xen_shared_info)
        __xen_shared_info_end__ = . ;
    }

    .xen_hypercall_page 0x00108000 ALIGN (0x4000) :
    {
        __xen_hypercall_page_start__ = . ;
        *(.xen_hypercall_page)
        __xen_hypercall_page_end__ = . ;
    }

    .rodata ALIGN (0x1000) :
    {
        __rodata_start__ = . ;
        *(.rodata)
        *(.rdata)
         __rodata_end__ = . ;
    }

    .data ALIGN (0x1000) :
    {
        __data_start__ = . ;
        *(.data)
        __data_end__ = . ;
    }

    .note ALIGN (0x1000) :
    {
        __note_start__ = . ;
        *(.note.*)
        __note_end__ = . ;
    }

    .bss ALIGN (0x1000) :
    {
        __bss_start__ = . ;
        *(COMMON)
        *(.bss)
        __bss_end__ = . ;
    }

    .end ALIGN (0x1000) :
    {
        __image_end__ = . ;
    }
}


x86: implement new linker variables

x86: implement new linker variables

Signed-off-by: Andrew Boie <aab045b28152628be6af0e556050d0381fd0a34d@intel.com>

/*
 * Copyright (c) 2013-2014 Wind River Systems, Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file
 * @brief Common linker sections
 *
 * This script defines the memory location of the various sections that make up
 * a Zephyr Kernel image. This file is used by the linker.
 *
 * This script places the various sections of the image according to what
 * features are enabled by the kernel's configuration options.
 *
 * For a build that does not use the execute in place (XIP) feature, the script
 * generates an image suitable for loading into and executing from RAMABLE_REGION by
 * placing all the sections adjacent to each other.  There is also no separate
 * load address for the DATA section which means it doesn't have to be copied
 * into RAMABLE_REGION.
 *
 * For builds using XIP, there is a different load memory address (LMA) and
 * virtual memory address (VMA) for the DATA section.  In this case the DATA
 * section is copied into RAMABLE_REGION at runtime.
 *
 * When building an XIP image the data section is placed into ROMABLE_REGION.  In this
 * case, the LMA is set to __data_rom_start so the data section is concatenated
 * at the end of the RODATA section.  At runtime, the DATA section is copied
 * into the RAMABLE_REGION region so it can be accessed with read and write permission.
 *
 * Most symbols defined in the sections below are subject to be referenced in
 * the Zephyr Kernel image. If a symbol is used but not defined the linker will
 * emit an undefined symbol error.
 *
 * Please do not change the order of the section as the kernel expects this
 * order when programming the MMU.
 */

#define _LINKER

#define _ASMLANGUAGE
#include <linker/linker-defs.h>
#include <offsets.h>
#include <misc/util.h>

#include <linker/linker-tool.h>

#ifdef CONFIG_XIP
	#define ROMABLE_REGION ROM
	#define RAMABLE_REGION RAM
#else
	#define ROMABLE_REGION RAM
	#define RAMABLE_REGION RAM
#endif

#ifdef CONFIG_X86_MMU
	#define MMU_PAGE_SIZE	KB(4)
	#define MMU_PAGE_ALIGN	. = ALIGN(MMU_PAGE_SIZE);
#else
	#define MMU_PAGE_ALIGN
#endif

/* SECTIONS definitions */
SECTIONS
	{
	GROUP_START(ROMABLE_REGION)

	_image_rom_start = PHYS_LOAD_ADDR;
	_image_text_start = PHYS_LOAD_ADDR;

	SECTION_PROLOGUE(_TEXT_SECTION_NAME, (OPTIONAL),)
	{
	. = CONFIG_TEXT_SECTION_OFFSET;
	*(.text_start)
	*(".text_start.*")
	*(.text)
	*(".text.*")
	*(.gnu.linkonce.t.*)
	*(.eh_frame)
	*(.init)
	*(.fini)
	*(.eini)
	KEEP(*(.openocd_dbg))
	KEEP(*(".openocd_dbg.*"))
	} GROUP_LINK_IN(ROMABLE_REGION)

	_image_text_end = .;
	_image_rodata_start = .;

#include <linker/common-rom.ld>

	SECTION_PROLOGUE(_RODATA_SECTION_NAME, (OPTIONAL),)
	{
	*(.rodata)
	*(".rodata.*")
	*(.gnu.linkonce.r.*)

	. = ALIGN(8);
	_idt_base_address = .;
#ifdef LINKER_PASS2
	KEEP(*(staticIdt))
#else
	. += CONFIG_IDT_NUM_VECTORS * 8;
#endif

#ifndef CONFIG_X86_FIXED_IRQ_MAPPING
	. = ALIGN(4);
	_irq_to_interrupt_vector = .;
#ifdef LINKER_PASS2
	KEEP(*(irq_int_vector_map))
#else
	. += CONFIG_MAX_IRQ_LINES;
#endif
#endif

#ifdef CONFIG_CUSTOM_RODATA_LD
/* Located in project source directory */
#include <custom-rodata.ld>
#endif

	} GROUP_LINK_IN(ROMABLE_REGION)

	_image_rodata_end = .;

	/* This align directive needs to be after __data_rom_start or XIP
	 * won't be copying the data from the right LMA
	 */
	MMU_PAGE_ALIGN
	_image_rom_end = .;
	_image_rom_size = _image_rom_end - _image_rom_start;

	GROUP_END(ROMABLE_REGION)

	/* RAMABLE_REGION */
	GROUP_START(RAMABLE_REGION)

#ifdef CONFIG_APPLICATION_MEMORY
	SECTION_DATA_PROLOGUE(_APP_DATA_SECTION_NAME, (OPTIONAL),)
	{
		_image_ram_start = .;
		__app_ram_start = .;
		__app_data_ram_start = .;
		APP_INPUT_SECTION(.data)
		APP_INPUT_SECTION(".data.*")
		__app_data_ram_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	__app_data_rom_start = LOADADDR(_APP_DATA_SECTION_NAME);

	SECTION_PROLOGUE(_APP_BSS_SECTION_NAME, (NOLOAD OPTIONAL),)
	{
		__app_bss_start = .;
		APP_INPUT_SECTION(.bss)
		APP_INPUT_SECTION(".bss.*")
		APP_INPUT_SECTION(COMMON)
		__app_bss_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION)

	__app_bss_num_words = (__app_bss_end - __app_bss_start) >> 2;

	SECTION_PROLOGUE(_APP_NOINIT_SECTION_NAME, (NOLOAD OPTIONAL),)
	{
		APP_INPUT_SECTION(.noinit)
		APP_INPUT_SECTION(".noinit.*")
		MMU_PAGE_ALIGN
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION)

	__app_ram_end = .;
	__app_ram_size = __app_ram_end - __app_ram_start;
#endif /* CONFIG_APPLICATION_MEMORY */

	SECTION_DATA_PROLOGUE(_DATA_SECTION_NAME, (OPTIONAL),)
	{
#ifndef CONFIG_APPLICATION_MEMORY
	_image_ram_start = .;
#endif
	__kernel_ram_start = .;
	__data_ram_start = .;

	KERNEL_INPUT_SECTION(.data)
	KERNEL_INPUT_SECTION(".data.*")
	*(".kernel.*")

#ifdef CONFIG_CUSTOM_RWDATA_LD
/* Located in project source directory */
#include <custom-rwdata.ld>
#endif

#ifdef CONFIG_GDT_DYNAMIC
	KEEP(*(.tss))
	. = ALIGN(8);
	_gdt = .;
#ifdef LINKER_PASS2
	KEEP(*(gdt_ram_data))
#else /* LINKER_PASS2 */

#ifdef CONFIG_X86_STACK_PROTECTION
#define GDT_NUM_ENTRIES	5
#else /* CONFIG_X86_STACK_PROTECTION */
#define GDT_NUM_ENTRIES 3
#endif /* CONFIG_X86_STACK_PROTECTION */

	. += GDT_NUM_ENTRIES * 8;
#endif /* LINKER_PASS2 */
#endif /* CONFIG_GDT_DYNAMIC */

#ifdef CONFIG_X86_MMU
	/* Page Tables are located here if MMU is enabled.*/
	MMU_PAGE_ALIGN
	__mmu_tables_start = .;
	KEEP(*(.mmu_data));
	__mmu_tables_end = .;
#endif
	. = ALIGN(4);
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	__data_rom_start = LOADADDR(_DATA_SECTION_NAME);

#include <linker/common-ram.ld>

	__data_ram_end = .;

	SECTION_PROLOGUE(_BSS_SECTION_NAME, (NOLOAD OPTIONAL),)
	{
	/*
	 * For performance, BSS section is forced to be both 4 byte aligned and
	 * a multiple of 4 bytes.
	 */

	. = ALIGN(4);

	__bss_start = .;

	KERNEL_INPUT_SECTION(.bss)
	KERNEL_INPUT_SECTION(".bss.*")
	KERNEL_INPUT_SECTION(COMMON)
	*(".kernel_bss.*")

	/*
	 * As memory is cleared in words only, it is simpler to ensure the BSS
	 * section ends on a 4 byte boundary. This wastes a maximum of 3 bytes.
	 */
	. = ALIGN(4);
	__bss_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION)

	__bss_num_words	= (__bss_end - __bss_start) >> 2;

	SECTION_PROLOGUE(_NOINIT_SECTION_NAME, (NOLOAD OPTIONAL),)
	{
	/*
	 * This section is used for non-initialized objects that
	 * will not be cleared during the boot process.
	 */
	KERNEL_INPUT_SECTION(.noinit)
	KERNEL_INPUT_SECTION(".noinit.*")
	*(".kernel_noinit.*")

	/* All stacks go in kernel's noinit, regardless of where they
	 * were defined.
	 */
	*(.stacks)
	*(".stacks.*")

	MMU_PAGE_ALIGN

	} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION)

	/* All unused memory also owned by the kernel for heaps */
	__kernel_ram_end = PHYS_RAM_ADDR + KB(CONFIG_RAM_SIZE);
	__kernel_ram_size = __kernel_ram_end - __kernel_ram_start;

	_image_ram_end = .;
	_image_ram_all = (PHYS_RAM_ADDR + KB(CONFIG_RAM_SIZE)) - _image_ram_start;

	_end = .; /* end of image */

	GROUP_END(RAMABLE_REGION)

#ifndef LINKER_PASS2
	/* static interrupts */
	SECTION_PROLOGUE(intList, (OPTIONAL),)
	{
	KEEP(*(.spurIsr))
	KEEP(*(.spurNoErrIsr))
	__INT_LIST_START__ = .;
	LONG((__INT_LIST_END__ - __INT_LIST_START__) / __ISR_LIST_SIZEOF)
	KEEP(*(.intList))
	KEEP(*(.gnu.linkonce.intList.*))
	__INT_LIST_END__ = .;
	} > IDT_LIST

#ifdef CONFIG_X86_MMU
	/* Memory management unit*/
	SECTION_PROLOGUE(mmulist, (OPTIONAL),)
	{
	/* get size of the mmu lists needed for gen_mmu.py*/
	LONG((__MMU_LIST_END__ - __MMU_LIST_START__) / __MMU_REGION_SIZEOF)
	/* Get the start of mmu tables in data section so that the address
	 * of the page tables can be calculated.
	 */
	LONG(__mmu_tables_start)
	__MMU_LIST_START__ = .;
	KEEP(*(.mmulist))
	__MMU_LIST_END__ = .;
	} > MMU_LIST
#endif /* CONFIG_X86_MMU */

#else
	/DISCARD/ :
	{
	KEEP(*(.spurIsr))
	KEEP(*(.spurNoErrIsr))
	KEEP(*(.intList))
	KEEP(*(.gnu.linkonce.intList.*))
	KEEP(*(.mmulist))
	}
#endif

#ifdef CONFIG_CUSTOM_SECTIONS_LD
/* Located in project source directory */
#include <custom-sections.ld>
#endif

	}

#ifdef CONFIG_XIP
/*
 * Round up number of words for DATA section to ensure that XIP copies the
 * entire data section. XIP copy is done in words only, so there may be up
 * to 3 extra bytes copied in next section (BSS). At run time, the XIP copy
 * is done first followed by clearing the BSS section.
 */
__data_size = (__data_ram_end - __data_ram_start);
__data_num_words = (__data_size + 3) >> 2;
#ifdef CONFIG_APPLICATION_MEMORY
__app_data_size = (__app_data_ram_end - __app_data_ram_start);
__app_data_num_words = (__app_data_size + 3) >> 2;
#endif

#endif

/*
 * Copyright (c) 2013-2014 Wind River Systems, Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file
 * @brief Common linker sections
 *
 * This script defines the memory location of the various sections that make up
 * a Zephyr Kernel image. This file is used by the linker.
 *
 * This script places the various sections of the image according to what
 * features are enabled by the kernel's configuration options.
 *
 * For a build that does not use the execute in place (XIP) feature, the script
 * generates an image suitable for loading into and executing from RAMABLE_REGION by
 * placing all the sections adjacent to each other.  There is also no separate
 * load address for the DATA section which means it doesn't have to be copied
 * into RAMABLE_REGION.
 *
 * For builds using XIP, there is a different load memory address (LMA) and
 * virtual memory address (VMA) for the DATA section.  In this case the DATA
 * section is copied into RAMABLE_REGION at runtime.
 *
 * When building an XIP image the data section is placed into ROMABLE_REGION.  In this
 * case, the LMA is set to __data_rom_start so the data section is concatenated
 * at the end of the RODATA section.  At runtime, the DATA section is copied
 * into the RAMABLE_REGION region so it can be accessed with read and write permission.
 *
 * Most symbols defined in the sections below are subject to be referenced in
 * the Zephyr Kernel image. If a symbol is used but not defined the linker will
 * emit an undefined symbol error.
 *
 * Please do not change the order of the section as the kernel expects this
 * order when programming the MMU.
 */

#define _LINKER

#define _ASMLANGUAGE
#include <linker/linker-defs.h>
#include <offsets.h>
#include <misc/util.h>

#include <linker/linker-tool.h>

#ifdef CONFIG_XIP
	#define ROMABLE_REGION ROM
	#define RAMABLE_REGION RAM
#else
	#define ROMABLE_REGION RAM
	#define RAMABLE_REGION RAM
#endif

#ifdef CONFIG_X86_MMU
	#define MMU_PAGE_SIZE	KB(4)
	#define MMU_PAGE_ALIGN	. = ALIGN(MMU_PAGE_SIZE);
#else
	#define MMU_PAGE_ALIGN
#endif

/* SECTIONS definitions */
SECTIONS
	{
	GROUP_START(ROMABLE_REGION)

	_image_rom_start = PHYS_LOAD_ADDR;
	_image_text_start = PHYS_LOAD_ADDR;

	SECTION_PROLOGUE(_TEXT_SECTION_NAME, (OPTIONAL),)
	{
	. = CONFIG_TEXT_SECTION_OFFSET;
	*(.text_start)
	*(".text_start.*")
	*(.text)
	*(".text.*")
	*(.gnu.linkonce.t.*)
	*(.eh_frame)
	*(.init)
	*(.fini)
	*(.eini)
	KEEP(*(.openocd_dbg))
	KEEP(*(".openocd_dbg.*"))
	} GROUP_LINK_IN(ROMABLE_REGION)

	_image_text_end = .;
	_image_rodata_start = .;

#include <linker/common-rom.ld>

	SECTION_PROLOGUE(_RODATA_SECTION_NAME, (OPTIONAL),)
	{
	*(.rodata)
	*(".rodata.*")
	*(.gnu.linkonce.r.*)

	. = ALIGN(8);
	_idt_base_address = .;
#ifdef LINKER_PASS2
	KEEP(*(staticIdt))
#else
	. += CONFIG_IDT_NUM_VECTORS * 8;
#endif

#ifndef CONFIG_X86_FIXED_IRQ_MAPPING
	. = ALIGN(4);
	_irq_to_interrupt_vector = .;
#ifdef LINKER_PASS2
	KEEP(*(irq_int_vector_map))
#else
	. += CONFIG_MAX_IRQ_LINES;
#endif
#endif

#ifdef CONFIG_CUSTOM_RODATA_LD
/* Located in project source directory */
#include <custom-rodata.ld>
#endif

	} GROUP_LINK_IN(ROMABLE_REGION)

	_image_rodata_end = .;

	/* This align directive needs to be after __data_rom_start or XIP
	 * won't be copying the data from the right LMA
	 */
	MMU_PAGE_ALIGN
	_image_rom_end = .;
	_image_rom_size = _image_rom_end - _image_rom_start;

	GROUP_END(ROMABLE_REGION)

	/* RAMABLE_REGION */
	GROUP_START(RAMABLE_REGION)

#ifdef CONFIG_APPLICATION_MEMORY
	SECTION_DATA_PROLOGUE(_APP_DATA_SECTION_NAME, (OPTIONAL),)
	{
		_image_ram_start = .;
		__app_ram_start = .;
		__app_data_ram_start = .;
		APP_INPUT_SECTION(.data)
		APP_INPUT_SECTION(".data.*")
		__app_data_ram_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	__app_data_rom_start = LOADADDR(_APP_DATA_SECTION_NAME);

	SECTION_PROLOGUE(_APP_BSS_SECTION_NAME, (NOLOAD OPTIONAL),)
	{
		__app_bss_start = .;
		APP_INPUT_SECTION(.bss)
		APP_INPUT_SECTION(".bss.*")
		APP_INPUT_SECTION(COMMON)
		__app_bss_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION)

	__app_bss_num_words = (__app_bss_end - __app_bss_start) >> 2;

	SECTION_PROLOGUE(_APP_NOINIT_SECTION_NAME, (NOLOAD OPTIONAL),)
	{
		APP_INPUT_SECTION(.noinit)
		APP_INPUT_SECTION(".noinit.*")
		MMU_PAGE_ALIGN
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION)

	__app_ram_end = .;
#endif /* CONFIG_APPLICATION_MEMORY */

	SECTION_DATA_PROLOGUE(_DATA_SECTION_NAME, (OPTIONAL),)
	{
#ifndef CONFIG_APPLICATION_MEMORY
	_image_ram_start = .;
#endif
	__kernel_ram_start = .;
	__data_ram_start = .;

	KERNEL_INPUT_SECTION(.data)
	KERNEL_INPUT_SECTION(".data.*")
	*(".kernel.*")

#ifdef CONFIG_CUSTOM_RWDATA_LD
/* Located in project source directory */
#include <custom-rwdata.ld>
#endif

#ifdef CONFIG_GDT_DYNAMIC
	KEEP(*(.tss))
	. = ALIGN(8);
	_gdt = .;
#ifdef LINKER_PASS2
	KEEP(*(gdt_ram_data))
#else /* LINKER_PASS2 */

#ifdef CONFIG_X86_STACK_PROTECTION
#define GDT_NUM_ENTRIES	5
#else /* CONFIG_X86_STACK_PROTECTION */
#define GDT_NUM_ENTRIES 3
#endif /* CONFIG_X86_STACK_PROTECTION */

	. += GDT_NUM_ENTRIES * 8;
#endif /* LINKER_PASS2 */
#endif /* CONFIG_GDT_DYNAMIC */

#ifdef CONFIG_X86_MMU
	/* Page Tables are located here if MMU is enabled.*/
	MMU_PAGE_ALIGN
	__mmu_tables_start = .;
	KEEP(*(.mmu_data));
	__mmu_tables_end = .;
#endif
	. = ALIGN(4);
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)

	__data_rom_start = LOADADDR(_DATA_SECTION_NAME);

#include <linker/common-ram.ld>

	__data_ram_end = .;

	SECTION_PROLOGUE(_BSS_SECTION_NAME, (NOLOAD OPTIONAL),)
	{
	/*
	 * For performance, BSS section is forced to be both 4 byte aligned and
	 * a multiple of 4 bytes.
	 */

	. = ALIGN(4);

	__bss_start = .;

	KERNEL_INPUT_SECTION(.bss)
	KERNEL_INPUT_SECTION(".bss.*")
	KERNEL_INPUT_SECTION(COMMON)
	*(".kernel_bss.*")

	/*
	 * As memory is cleared in words only, it is simpler to ensure the BSS
	 * section ends on a 4 byte boundary. This wastes a maximum of 3 bytes.
	 */
	. = ALIGN(4);
	__bss_end = .;
	} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION)

	__bss_num_words	= (__bss_end - __bss_start) >> 2;

	SECTION_PROLOGUE(_NOINIT_SECTION_NAME, (NOLOAD OPTIONAL),)
	{
	/*
	 * This section is used for non-initialized objects that
	 * will not be cleared during the boot process.
	 */
	KERNEL_INPUT_SECTION(.noinit)
	KERNEL_INPUT_SECTION(".noinit.*")
	*(".kernel_noinit.*")

	/* All stacks go in kernel's noinit, regardless of where they
	 * were defined.
	 */
	*(.stacks)
	*(".stacks.*")

	MMU_PAGE_ALIGN

	} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION)

	/* Define linker symbols */
	__kernel_ram_end = .;
	_image_ram_end = .;
	_image_ram_all = (PHYS_RAM_ADDR + KB(CONFIG_RAM_SIZE)) - _image_ram_start;

	_end = .; /* end of image */

	GROUP_END(RAMABLE_REGION)

#ifndef LINKER_PASS2
	/* static interrupts */
	SECTION_PROLOGUE(intList, (OPTIONAL),)
	{
	KEEP(*(.spurIsr))
	KEEP(*(.spurNoErrIsr))
	__INT_LIST_START__ = .;
	LONG((__INT_LIST_END__ - __INT_LIST_START__) / __ISR_LIST_SIZEOF)
	KEEP(*(.intList))
	KEEP(*(.gnu.linkonce.intList.*))
	__INT_LIST_END__ = .;
	} > IDT_LIST

#ifdef CONFIG_X86_MMU
	/* Memory management unit*/
	SECTION_PROLOGUE(mmulist, (OPTIONAL),)
	{
	/* get size of the mmu lists needed for gen_mmu.py*/
	LONG((__MMU_LIST_END__ - __MMU_LIST_START__) / __MMU_REGION_SIZEOF)
	/* Get the start of mmu tables in data section so that the address
	 * of the page tables can be calculated.
	 */
	LONG(__mmu_tables_start)
	__MMU_LIST_START__ = .;
	KEEP(*(.mmulist))
	__MMU_LIST_END__ = .;
	} > MMU_LIST
#endif /* CONFIG_X86_MMU */

#else
	/DISCARD/ :
	{
	KEEP(*(.spurIsr))
	KEEP(*(.spurNoErrIsr))
	KEEP(*(.intList))
	KEEP(*(.gnu.linkonce.intList.*))
	KEEP(*(.mmulist))
	}
#endif

#ifdef CONFIG_CUSTOM_SECTIONS_LD
/* Located in project source directory */
#include <custom-sections.ld>
#endif

	}

#ifdef CONFIG_XIP
/*
 * Round up number of words for DATA section to ensure that XIP copies the
 * entire data section. XIP copy is done in words only, so there may be up
 * to 3 extra bytes copied in next section (BSS). At run time, the XIP copy
 * is done first followed by clearing the BSS section.
 */
__data_size = (__data_ram_end - __data_ram_start);
__data_num_words = (__data_size + 3) >> 2;
#ifdef CONFIG_APPLICATION_MEMORY
__app_data_size = (__app_data_ram_end - __app_data_ram_start);
__app_data_num_words = (__app_data_size + 3) >> 2;
#endif

#endif


userland_generic.ld: Include .sdata in the data section

If an ELF has a .sdata section it won't be copied to the TBF file. To
ensure that it makes it in let's include it in the data section.

Signed-off-by: Alistair Francis <52ecf00b70a50079ae8d5fa09b9af6904950b63c@wdc.com>

/* Userland Generic Layout
 *
 * This linker script is designed for Tock apps where the end microcontroller
 * is not known. Therefore, this script over provisions space on some platforms.
 */

/* Memory Spaces Definitions, 448K flash, 64K ram */
PROG_LENGTH = 0x00040000;
RAM_LENGTH  = 0x00010000;

ENTRY(_start)

/* Note: Because apps are relocated, the FLASH address here acts as a sentinel
 * value for relocation fixup routines. The application loader will select the
 * actual location in flash where the app is placed.
 */
MEMORY {
    FLASH (rx) : ORIGIN = 0x80000000, LENGTH = PROG_LENGTH
    SRAM (RWX) : ORIGIN = 0x00000000, LENGTH = RAM_LENGTH
}

SECTIONS {
    /* Section for just the app crt0 header.
     * This must be first so that the app can find it.
     */
    .crt0_header :
    {
        _beginning = .; /* Start of the app in flash. */
        /**
         * Populate the header expected by `crt0`:
         *
         *  struct hdr {
         *    uint32_t got_sym_start;
         *    uint32_t got_start;
         *    uint32_t got_size;
         *    uint32_t data_sym_start;
         *    uint32_t data_start;
         *    uint32_t data_size;
         *    uint32_t bss_start;
         *    uint32_t bss_size;
         *    uint32_t reldata_start;
         *    uint32_t stack_size;
         *  };
         */
        /* Offset of GOT symbols in flash */
        LONG(LOADADDR(.got) - _beginning);
        /* Offset of GOT section in memory */
        LONG(_got);
        /* Size of GOT section */
        LONG(SIZEOF(.got));
        /* Offset of data symbols in flash */
        LONG(LOADADDR(.data) - _beginning);
        /* Offset of data section in memory */
        LONG(_data);
        /* Size of data section */
        LONG(SIZEOF(.data));
        /* Offset of BSS section in memory */
        LONG(_bss);
        /* Size of BSS section */
        LONG(SIZEOF(.bss));
        /* First address offset after program flash, where elf2tab places
         * .rel.data section */
        LONG(LOADADDR(.endflash) - _beginning);
        /* The size of the stack requested by this application */
        LONG(STACK_SIZE);
    } > FLASH =0xFF

    /* App state section. Used for persistent app data.
     * We put this first so that if the app code changes but the persistent
     * data doesn't, the app_state can be preserved.
     */
    .wfr.app_state :
    {
        KEEP (*(.app_state))
        . = ALIGN(4); /* Make sure we're word-aligned here */
    } > FLASH =0xFF

    /* Text section, Code! */
    .text :
    {
        . = ALIGN(4);
        _text = .;
        KEEP (*(.start))
        *(.text*)
        *(.rodata*)
        KEEP (*(.syscalls))
        _etext = .;
        *(.ARM.extab*)
        . = ALIGN(4); /* Make sure we're word-aligned here */
    } > FLASH =0xFF

    /* Global Offset Table */
    .got :
    {
        . = ALIGN(4); /* Make sure we're word-aligned here */
        _got = .;
        *(.got*)
        *(.got.plt*)
        . = ALIGN(4);
    } > SRAM AT > FLASH

    /* Data section, static initialized variables
     *  Note: This is placed in Flash after the text section, but needs to be
     *  moved to SRAM at runtime
     */
    .data :
    {
        . = ALIGN(4); /* Make sure we're word-aligned here */
        _data = .;
        KEEP(*(.data*))
	/* Include the "small data" in the data section. Otherwise it will be
	 * dropped when the TBF is created.
	 */
        KEEP(*(.sdata*))
        . = ALIGN(4); /* Make sure we're word-aligned at the end of flash */
    } > SRAM AT > FLASH

    /* BSS section, static uninitialized variables */
    .bss :
    {
        . = ALIGN(4); /* Make sure we're word-aligned here */
        _bss = .;
        KEEP(*(.bss*))
        *(COMMON)
        . = ALIGN(4);
    } > SRAM

    /* End of flash. */
    .endflash :
    {
    } > FLASH

    /* ARM Exception support
     *
     * This contains compiler-generated support for unwinding the stack,
     * consisting of key-value pairs of function addresses and information on
     * how to unwind stack frames.
     * https://wiki.linaro.org/KenWerner/Sandbox/libunwind?action=AttachFile&do=get&target=libunwind-LDS.pdf
     *
     * .ARM.exidx is sorted, so has to go in its own output section.
     *
     * __NOTE__: It's at the end because we currently don't actually serialize
     * it to the binary in elf2tab. If it was before the RAM sections, it would
     * through off our calculations of the header.
     */
    PROVIDE_HIDDEN (__exidx_start = .);
    .ARM.exidx :
    {
      /* (C++) Index entries for section unwinding */
      *(.ARM.exidx* .gnu.linkonce.armexidx.*)
    } > FLASH
    PROVIDE_HIDDEN (__exidx_end = .);
}

ASSERT(_got <= _bss, "
The GOT section must be before the BSS section for crt0 setup to be correct.");
ASSERT(_data <= _bss, "
The data section must be before the BSS section for crt0 setup to be correct.");

/* Userland Generic Layout
 *
 * This linker script is designed for Tock apps where the end microcontroller
 * is not known. Therefore, this script over provisions space on some platforms.
 */

/* Memory Spaces Definitions, 448K flash, 64K ram */
PROG_LENGTH = 0x00040000;
RAM_LENGTH  = 0x00010000;

ENTRY(_start)

/* Note: Because apps are relocated, the FLASH address here acts as a sentinel
 * value for relocation fixup routines. The application loader will select the
 * actual location in flash where the app is placed.
 */
MEMORY {
    FLASH (rx) : ORIGIN = 0x80000000, LENGTH = PROG_LENGTH
    SRAM (RWX) : ORIGIN = 0x00000000, LENGTH = RAM_LENGTH
}

SECTIONS {
    /* Section for just the app crt0 header.
     * This must be first so that the app can find it.
     */
    .crt0_header :
    {
        _beginning = .; /* Start of the app in flash. */
        /**
         * Populate the header expected by `crt0`:
         *
         *  struct hdr {
         *    uint32_t got_sym_start;
         *    uint32_t got_start;
         *    uint32_t got_size;
         *    uint32_t data_sym_start;
         *    uint32_t data_start;
         *    uint32_t data_size;
         *    uint32_t bss_start;
         *    uint32_t bss_size;
         *    uint32_t reldata_start;
         *    uint32_t stack_size;
         *  };
         */
        /* Offset of GOT symbols in flash */
        LONG(LOADADDR(.got) - _beginning);
        /* Offset of GOT section in memory */
        LONG(_got);
        /* Size of GOT section */
        LONG(SIZEOF(.got));
        /* Offset of data symbols in flash */
        LONG(LOADADDR(.data) - _beginning);
        /* Offset of data section in memory */
        LONG(_data);
        /* Size of data section */
        LONG(SIZEOF(.data));
        /* Offset of BSS section in memory */
        LONG(_bss);
        /* Size of BSS section */
        LONG(SIZEOF(.bss));
        /* First address offset after program flash, where elf2tab places
         * .rel.data section */
        LONG(LOADADDR(.endflash) - _beginning);
        /* The size of the stack requested by this application */
        LONG(STACK_SIZE);
    } > FLASH =0xFF

    /* App state section. Used for persistent app data.
     * We put this first so that if the app code changes but the persistent
     * data doesn't, the app_state can be preserved.
     */
    .wfr.app_state :
    {
        KEEP (*(.app_state))
        . = ALIGN(4); /* Make sure we're word-aligned here */
    } > FLASH =0xFF

    /* Text section, Code! */
    .text :
    {
        . = ALIGN(4);
        _text = .;
        KEEP (*(.start))
        *(.text*)
        *(.rodata*)
        KEEP (*(.syscalls))
        _etext = .;
        *(.ARM.extab*)
        . = ALIGN(4); /* Make sure we're word-aligned here */
    } > FLASH =0xFF

    /* Global Offset Table */
    .got :
    {
        . = ALIGN(4); /* Make sure we're word-aligned here */
        _got = .;
        *(.got*)
        *(.got.plt*)
        . = ALIGN(4);
    } > SRAM AT > FLASH

    /* Data section, static initialized variables
     *  Note: This is placed in Flash after the text section, but needs to be
     *  moved to SRAM at runtime
     */
    .data :
    {
        . = ALIGN(4); /* Make sure we're word-aligned here */
        _data = .;
        KEEP(*(.data*))
        . = ALIGN(4); /* Make sure we're word-aligned at the end of flash */
    } > SRAM AT > FLASH

    /* BSS section, static uninitialized variables */
    .bss :
    {
        . = ALIGN(4); /* Make sure we're word-aligned here */
        _bss = .;
        KEEP(*(.bss*))
        *(COMMON)
        . = ALIGN(4);
    } > SRAM

    /* End of flash. */
    .endflash :
    {
    } > FLASH

    /* ARM Exception support
     *
     * This contains compiler-generated support for unwinding the stack,
     * consisting of key-value pairs of function addresses and information on
     * how to unwind stack frames.
     * https://wiki.linaro.org/KenWerner/Sandbox/libunwind?action=AttachFile&do=get&target=libunwind-LDS.pdf
     *
     * .ARM.exidx is sorted, so has to go in its own output section.
     *
     * __NOTE__: It's at the end because we currently don't actually serialize
     * it to the binary in elf2tab. If it was before the RAM sections, it would
     * through off our calculations of the header.
     */
    PROVIDE_HIDDEN (__exidx_start = .);
    .ARM.exidx :
    {
      /* (C++) Index entries for section unwinding */
      *(.ARM.exidx* .gnu.linkonce.armexidx.*)
    } > FLASH
    PROVIDE_HIDDEN (__exidx_end = .);
}

ASSERT(_got <= _bss, "
The GOT section must be before the BSS section for crt0 setup to be correct.");
ASSERT(_data <= _bss, "
The data section must be before the BSS section for crt0 setup to be correct.");


everyone gets a stack

everyone gets a stack

KERNEL_BASE   = 0xf0000000; /* virtual address */
PHYS_BASE     = 0x80000000; /* physical address */
KERNEL_OFFSET = KERNEL_BASE - PHYS_BASE;

ENTRY(asm_entry)
SECTIONS
{
    . = PHYS_BASE;

    .boot . :
    {
        *(.boot.text)
        *(.boot.rodata)
        *(.boot.data)
        . = . + 4K;
        . = ALIGN(8);
        _boot_stack = .;
    }

    . = . + KERNEL_OFFSET;

    .text . : AT(ADDR(.text) - KERNEL_OFFSET)
    {
        . = ALIGN(64K);
        *(.vectors)
        *(.vectors.text)
        *(.text)
    }
    .rodata . : AT(ADDR(.rodata) - KERNEL_OFFSET)
    {
        *(.rodata)
        *(.rodata.*)
    }

    .data . : AT(ADDR(.data) - KERNEL_OFFSET)
    {
        *(.data)
        . = ALIGN(8);
        . = . + 0x1000;
        svc_stack = .;
    }

    .bss . : AT(ADDR(.bss) - KERNEL_OFFSET)
    {
        *(.bss)
        *(COMMON)
        *(.bss.aligned)
    }

    /DISCARD/ :
    {
        *(.note.gnu.build-id)
        *(.comment)
        *(.ARM.attributes)
    }

}

KERNEL_BASE   = 0xf0000000; /* virtual address */
PHYS_BASE     = 0x80000000; /* physical address */
KERNEL_OFFSET = KERNEL_BASE - PHYS_BASE;

ENTRY(asm_entry)
SECTIONS
{
    . = PHYS_BASE;

    .boot . :
    {
        *(.boot.text)
        *(.boot.rodata)
        *(.boot.data)
    }

    . = . + KERNEL_OFFSET;

    .text . : AT(ADDR(.text) - KERNEL_OFFSET)
    {
        . = ALIGN(64K);
        *(.vectors)
        *(.vectors.text)
        *(.text)
    }
    .rodata . : AT(ADDR(.rodata) - KERNEL_OFFSET)
    {
        *(.rodata)
        *(.rodata.*)
    }

    .data . : AT(ADDR(.data) - KERNEL_OFFSET)
    {
        *(.data)
        . = ALIGN(8);
        . = . + 0x1000;
        svc_stack = .;
    }

    .bss . : AT(ADDR(.bss) - KERNEL_OFFSET)
    {
        *(.bss)
        *(COMMON)
        *(.bss.aligned)
    }

    /DISCARD/ :
    {
        *(.note.gnu.build-id)
        *(.comment)
        *(.ARM.attributes)
    }

}


m68k: Put .bss at the end of the data section

Put .bss at the end of the data section

Signed-off-by: Roman Zippel <f9f6ad990b4a8c1974dc6544787c1cc3570b6f00@linux-m68k.org>
Signed-off-by: Geert Uytterhoeven <0da414d9d963da4039c2a0525b1844228075aa58@linux-m68k.org>
Signed-off-by: Linus Torvalds <69652caca27c8b940640ad396ab71f93cacec34f@linux-foundation.org>

/* ld script to make m68k Linux kernel */

#include <asm-generic/vmlinux.lds.h>
#include <asm/page.h>

OUTPUT_FORMAT("elf32-m68k", "elf32-m68k", "elf32-m68k")
OUTPUT_ARCH(m68k)
ENTRY(_start)
jiffies = jiffies_64 + 4;
SECTIONS
{
  . = 0x1000;
  _text = .;			/* Text and read-only data */
  .text : {
	*(.text.head)
	TEXT_TEXT
	SCHED_TEXT
	LOCK_TEXT
	*(.fixup)
	*(.gnu.warning)
	} :text = 0x4e75

  _etext = .;			/* End of text section */

  . = ALIGN(16);		/* Exception table */
  __start___ex_table = .;
  __ex_table : { *(__ex_table) }
  __stop___ex_table = .;

  RODATA

  .data : {			/* Data */
	DATA_DATA
	CONSTRUCTORS
	}

  . = ALIGN(16);
  .data.cacheline_aligned : { *(.data.cacheline_aligned) }

  .bss : { *(.bss) }		/* BSS */

  _edata = .;			/* End of data section */

  /* will be freed after init */
  . = ALIGN(PAGE_SIZE);		/* Init code and data */
  __init_begin = .;
  .init.text : {
	_sinittext = .;
	INIT_TEXT
	_einittext = .;
  } :data
  .init.data : { INIT_DATA }
  . = ALIGN(16);
  __setup_start = .;
  .init.setup : { *(.init.setup) }
  __setup_end = .;
  __initcall_start = .;
  .initcall.init : {
	INITCALLS
  }
  __initcall_end = .;
  __con_initcall_start = .;
  .con_initcall.init : { *(.con_initcall.init) }
  __con_initcall_end = .;
  .m68k_fixup : {
	__start_fixup = .;
	*(.m68k_fixup)
	__stop_fixup = .;
  }
  SECURITY_INIT
#ifdef CONFIG_BLK_DEV_INITRD
  . = ALIGN(8192);
  __initramfs_start = .;
  .init.ramfs : { *(.init.ramfs) }
  __initramfs_end = .;
#endif
  . = ALIGN(8192);
  __init_end = .;

  .data.init_task : { *(.data.init_task) }	/* The initial task and kernel stack */

  _end = . ;

  /* Sections to be discarded */
  /DISCARD/ : {
	EXIT_TEXT
	EXIT_DATA
	*(.exitcall.exit)
	}

  /* Stabs debugging sections.  */
  .stab 0 : { *(.stab) }
  .stabstr 0 : { *(.stabstr) }
  .stab.excl 0 : { *(.stab.excl) }
  .stab.exclstr 0 : { *(.stab.exclstr) }
  .stab.index 0 : { *(.stab.index) }
  .stab.indexstr 0 : { *(.stab.indexstr) }
  .comment 0 : { *(.comment) }
}

/* ld script to make m68k Linux kernel */

#include <asm-generic/vmlinux.lds.h>
#include <asm/page.h>

OUTPUT_FORMAT("elf32-m68k", "elf32-m68k", "elf32-m68k")
OUTPUT_ARCH(m68k)
ENTRY(_start)
jiffies = jiffies_64 + 4;
SECTIONS
{
  . = 0x1000;
  _text = .;			/* Text and read-only data */
  .text : {
	*(.text.head)
	TEXT_TEXT
	SCHED_TEXT
	LOCK_TEXT
	*(.fixup)
	*(.gnu.warning)
	} :text = 0x4e75

  _etext = .;			/* End of text section */

  . = ALIGN(16);		/* Exception table */
  __start___ex_table = .;
  __ex_table : { *(__ex_table) }
  __stop___ex_table = .;

  RODATA

  .data : {			/* Data */
	DATA_DATA
	CONSTRUCTORS
	}

  .bss : { *(.bss) }		/* BSS */

  . = ALIGN(16);
  .data.cacheline_aligned : { *(.data.cacheline_aligned) } :data

  _edata = .;			/* End of data section */

  /* will be freed after init */
  . = ALIGN(PAGE_SIZE);		/* Init code and data */
  __init_begin = .;
  .init.text : {
	_sinittext = .;
	INIT_TEXT
	_einittext = .;
  }
  .init.data : { INIT_DATA }
  . = ALIGN(16);
  __setup_start = .;
  .init.setup : { *(.init.setup) }
  __setup_end = .;
  __initcall_start = .;
  .initcall.init : {
	INITCALLS
  }
  __initcall_end = .;
  __con_initcall_start = .;
  .con_initcall.init : { *(.con_initcall.init) }
  __con_initcall_end = .;
  .m68k_fixup : {
	__start_fixup = .;
	*(.m68k_fixup)
	__stop_fixup = .;
  }
  SECURITY_INIT
#ifdef CONFIG_BLK_DEV_INITRD
  . = ALIGN(8192);
  __initramfs_start = .;
  .init.ramfs : { *(.init.ramfs) }
  __initramfs_end = .;
#endif
  . = ALIGN(8192);
  __init_end = .;

  .data.init_task : { *(.data.init_task) }	/* The initial task and kernel stack */

  _end = . ;

  /* Sections to be discarded */
  /DISCARD/ : {
	EXIT_TEXT
	EXIT_DATA
	*(.exitcall.exit)
	}

  /* Stabs debugging sections.  */
  .stab 0 : { *(.stab) }
  .stabstr 0 : { *(.stabstr) }
  .stab.excl 0 : { *(.stab.excl) }
  .stab.exclstr 0 : { *(.stab.exclstr) }
  .stab.index 0 : { *(.stab.index) }
  .stab.indexstr 0 : { *(.stab.indexstr) }
  .comment 0 : { *(.comment) }
}


Align heap base on an 8-byte offset.

Align heap base on an 8-byte offset.

The MCU linker scripts were only imposing 4-byte alignment on the heap
base, rather than 8-byte alignment.  This caused `malloc()` to return
pointers that were not 8-byte aligned.  This is problematic if the
pointer were subsequently used to access data that requires 8-byte
alignment (e.g., a `double`).

From n1570 (c11 draft), 7.22.3 (Memory management functions):

    The pointer returned if the allocation succeeds is suitably aligned
    so that it may be assigned to a pointer to any type of object with a
    fundamental alignment requirement

By locating the heap base at an offset of 8, we ensure `_sbrk()` only
returns 8-byte aligned memory blocks.

`malloc()` itself already imposes a greater restriction on itself: it
only allocates blocks whose size is a multiple of 16.  So, as long as
`_sbrk()` gives malloc properly aligned blocks, `malloc()` will return
properly aligned pointers to the application.

/**
 * \file
 *
 * \brief Linker script for running in internal FLASH on the SAMD21G18A
 *
 * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved.
 *
 * \asf_license_start
 *
 * \page License
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * 3. The name of Atmel may not be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * 4. This software may only be redistributed and used in connection with an
 *    Atmel microcontroller product.
 *
 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * \asf_license_stop
 *
 */

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
SEARCH_DIR(.)

/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200;      /* required amount of heap  */
_Min_Stack_Size = 0x200; /* required amount of stack */

/* The stack size used by the application. NOTE: you need to adjust according to your application. */
STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x400;

ENTRY(Reset_Handler)

/* Section Definitions */
SECTIONS
{

    .imghdr (NOLOAD):
    {
        . = . + _imghdr_size;
    } > FLASH

    .text :
    {
        . = ALIGN(4);
        _sfixed = .;
        __isr_vector_start = .;
        KEEP(*(.vectors .vectors.*))
        __isr_vector_end = .;

        *(.text .text.* .gnu.linkonce.t.*)
        *(.glue_7t) *(.glue_7)
        *(.rodata .rodata* .gnu.linkonce.r.*)
        *(.ARM.extab* .gnu.linkonce.armextab.*)

        /* Support C constructors, and C destructors in both user code
           and the C library. This also provides support for C++ code. */
        . = ALIGN(4);
        KEEP(*(.init))
        . = ALIGN(4);
        __preinit_array_start = .;
        KEEP (*(.preinit_array))
        __preinit_array_end = .;

        . = ALIGN(4);
        __init_array_start = .;
        KEEP (*(SORT(.init_array.*)))
        KEEP (*(.init_array))
        __init_array_end = .;

        . = ALIGN(4);
        KEEP (*crtbegin.o(.ctors))
        KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
        KEEP (*(SORT(.ctors.*)))
        KEEP (*crtend.o(.ctors))

        . = ALIGN(4);
        KEEP(*(.fini))

        . = ALIGN(4);
        __fini_array_start = .;
        KEEP (*(.fini_array))
        KEEP (*(SORT(.fini_array.*)))
        __fini_array_end = .;

        KEEP (*crtbegin.o(.dtors))
        KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
        KEEP (*(SORT(.dtors.*)))
        KEEP (*crtend.o(.dtors))

        . = ALIGN(4);
        _efixed = .;            /* End of text section */
    } > FLASH

    /* .ARM.exidx is sorted, so has to go in its own output section.  */
    PROVIDE_HIDDEN (__exidx_start = .);
    .ARM.exidx :
    {
      *(.ARM.exidx* .gnu.linkonce.armexidx.*)
    } > FLASH
    PROVIDE_HIDDEN (__exidx_end = .);

    . = ALIGN(4);
    _etext = .;

    .vector_relocation :
    {
        . = ALIGN(4);
        __vector_tbl_reloc__ = .;
        . = . + (__isr_vector_end - __isr_vector_start);
        . = ALIGN(4);
    } > RAM

    .relocate :
    {
        . = ALIGN(4);
        _srelocate = .;
        *(.data .data.*);
        . = ALIGN(4);
        _erelocate = .;
    } > RAM AT > FLASH

    /* .bss section which is used for uninitialized data */
    .bss (NOLOAD) :
    {
        . = ALIGN(4);
	__bss_start__ = . ;
        _sbss = . ;
        _szero = .;
        *(.bss .bss.*)
        *(COMMON)
        . = ALIGN(4);
	__bss_end__ = . ;
        _ebss = . ;
        _ezero = .;
    } > RAM

    /* Heap starts after BSS */
    . = ALIGN(8);
    __HeapBase = .;

  /* User_heap_stack section, used to check that there is enough RAM left */
  .heap :
  {
    . = ALIGN(4);
    PROVIDE ( _user_heap_start = . );
    . = . + _Min_Heap_Size;
    . = ALIGN(4);
  } > RAM

    /* .stack_dummy section doesn't contains any symbols. It is only
     * used for linker to calculate size of stack sections, and assign
     * values to stack symbols later */
    .stack_dummy (COPY):
    {
        . = . + STACK_SIZE;
        *(.stack*)
    } > RAM

    _ram_start = ORIGIN(RAM);

    /* Set stack top to end of RAM, and stack limit move down by
     * size of stack_dummy section */
    __StackTop = ORIGIN(RAM) + LENGTH(RAM);
    __StackLimit = __StackTop - SIZEOF(.stack_dummy);
    PROVIDE(__stack = __StackTop);

    /* Top of head is the bottom of the stack */
  _user_heap_end = __StackLimit;
  __HeapLimit = __StackLimit;

    /* Check if data + heap + stack exceeds RAM limit */
    ASSERT(__HeapBase <= __HeapLimit, "region RAM overflowed with stack")
}

/**
 * \file
 *
 * \brief Linker script for running in internal FLASH on the SAMD21G18A
 *
 * Copyright (c) 2014-2015 Atmel Corporation. All rights reserved.
 *
 * \asf_license_start
 *
 * \page License
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * 3. The name of Atmel may not be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * 4. This software may only be redistributed and used in connection with an
 *    Atmel microcontroller product.
 *
 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * \asf_license_stop
 *
 */

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
SEARCH_DIR(.)

/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0x200;      /* required amount of heap  */
_Min_Stack_Size = 0x200; /* required amount of stack */

/* The stack size used by the application. NOTE: you need to adjust according to your application. */
STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x400;

ENTRY(Reset_Handler)

/* Section Definitions */
SECTIONS
{

    .imghdr (NOLOAD):
    {
        . = . + _imghdr_size;
    } > FLASH

    .text :
    {
        . = ALIGN(4);
        _sfixed = .;
        __isr_vector_start = .;
        KEEP(*(.vectors .vectors.*))
        __isr_vector_end = .;

        *(.text .text.* .gnu.linkonce.t.*)
        *(.glue_7t) *(.glue_7)
        *(.rodata .rodata* .gnu.linkonce.r.*)
        *(.ARM.extab* .gnu.linkonce.armextab.*)

        /* Support C constructors, and C destructors in both user code
           and the C library. This also provides support for C++ code. */
        . = ALIGN(4);
        KEEP(*(.init))
        . = ALIGN(4);
        __preinit_array_start = .;
        KEEP (*(.preinit_array))
        __preinit_array_end = .;

        . = ALIGN(4);
        __init_array_start = .;
        KEEP (*(SORT(.init_array.*)))
        KEEP (*(.init_array))
        __init_array_end = .;

        . = ALIGN(4);
        KEEP (*crtbegin.o(.ctors))
        KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
        KEEP (*(SORT(.ctors.*)))
        KEEP (*crtend.o(.ctors))

        . = ALIGN(4);
        KEEP(*(.fini))

        . = ALIGN(4);
        __fini_array_start = .;
        KEEP (*(.fini_array))
        KEEP (*(SORT(.fini_array.*)))
        __fini_array_end = .;

        KEEP (*crtbegin.o(.dtors))
        KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
        KEEP (*(SORT(.dtors.*)))
        KEEP (*crtend.o(.dtors))

        . = ALIGN(4);
        _efixed = .;            /* End of text section */
    } > FLASH

    /* .ARM.exidx is sorted, so has to go in its own output section.  */
    PROVIDE_HIDDEN (__exidx_start = .);
    .ARM.exidx :
    {
      *(.ARM.exidx* .gnu.linkonce.armexidx.*)
    } > FLASH
    PROVIDE_HIDDEN (__exidx_end = .);

    . = ALIGN(4);
    _etext = .;

    .vector_relocation :
    {
        . = ALIGN(4);
        __vector_tbl_reloc__ = .;
        . = . + (__isr_vector_end - __isr_vector_start);
        . = ALIGN(4);
    } > RAM

    .relocate :
    {
        . = ALIGN(4);
        _srelocate = .;
        *(.data .data.*);
        . = ALIGN(4);
        _erelocate = .;
    } > RAM AT > FLASH

    /* .bss section which is used for uninitialized data */
    .bss (NOLOAD) :
    {
        . = ALIGN(4);
	__bss_start__ = . ;
        _sbss = . ;
        _szero = .;
        *(.bss .bss.*)
        *(COMMON)
        . = ALIGN(4);
	__bss_end__ = . ;
        _ebss = . ;
        _ezero = .;
    } > RAM

    /* Heap starts after BSS */
    __HeapBase = .;

  /* User_heap_stack section, used to check that there is enough RAM left */
  .heap :
  {
    . = ALIGN(4);
    PROVIDE ( _user_heap_start = . );
    . = . + _Min_Heap_Size;
    . = ALIGN(4);
  } > RAM

    /* .stack_dummy section doesn't contains any symbols. It is only
     * used for linker to calculate size of stack sections, and assign
     * values to stack symbols later */
    .stack_dummy (COPY):
    {
        . = . + STACK_SIZE;
        *(.stack*)
    } > RAM

    _ram_start = ORIGIN(RAM);

    /* Set stack top to end of RAM, and stack limit move down by
     * size of stack_dummy section */
    __StackTop = ORIGIN(RAM) + LENGTH(RAM);
    __StackLimit = __StackTop - SIZEOF(.stack_dummy);
    PROVIDE(__stack = __StackTop);

    /* Top of head is the bottom of the stack */
  _user_heap_end = __StackLimit;
  __HeapLimit = __StackLimit;

    /* Check if data + heap + stack exceeds RAM limit */
    ASSERT(__HeapBase <= __HeapLimit, "region RAM overflowed with stack")
}


arch: arm: aarch32: fix section alignment behind rodata region start marker

Fix for issue 39978. This commit assigns the __rodata_region_start marker
to the ROMABLE region prior to the inclusion of linker/common-rom.ld,
linker/thread-local-storage.ld and linker/cplusplus-rom.ld. Prior to this
fix, the __rodata_region_start marker was properly aligned and indicated
the expected memory location for the start of the rodata section and
similar sections, but it was disconnected from the ROMABLE region into
which the subsequent sections are being integrated, resulting in placement
of those sections right behind the previous section in the ROMABLE region
and therefore at addresses below the __rodata_region_start marker.

For the sake of consistent behaviour, the end marker of the text region
has been modified accordingly.

Signed-off-by: Immo Birnbaum <9d53277017f7b972042afc81794f782b84cac388@weidmueller.com>

/*
 * Copyright (c) 2013-2014 Wind River Systems, Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file
 * @brief Linker command/script file
 *
 * Linker script for the Cortex-A and Cortex-R platforms.
 */

#include <autoconf.h>
#include <linker/sections.h>
#include <devicetree.h>

#include <linker/devicetree_regions.h>
#include <linker/linker-defs.h>
#include <linker/linker-tool.h>

/* physical address of RAM */
#ifdef CONFIG_XIP
  #define ROMABLE_REGION FLASH
  #define RAMABLE_REGION SRAM
#else
  #define ROMABLE_REGION SRAM
  #define RAMABLE_REGION SRAM
#endif

#if !defined(CONFIG_XIP) && (CONFIG_FLASH_SIZE == 0)
  #define ROM_ADDR RAM_ADDR
#else
  #define ROM_ADDR (CONFIG_FLASH_BASE_ADDRESS + CONFIG_FLASH_LOAD_OFFSET)
#endif

#if CONFIG_FLASH_LOAD_SIZE > 0
  #define ROM_SIZE CONFIG_FLASH_LOAD_SIZE
#else
  #define ROM_SIZE (CONFIG_FLASH_SIZE*1K - CONFIG_FLASH_LOAD_OFFSET)
#endif

#if defined(CONFIG_XIP)
  #if defined(CONFIG_IS_BOOTLOADER)
    #define RAM_SIZE (CONFIG_BOOTLOADER_SRAM_SIZE * 1K)
    #define RAM_ADDR (CONFIG_SRAM_BASE_ADDRESS + \
                     (CONFIG_SRAM_SIZE * 1K - RAM_SIZE))
  #else
    #define RAM_SIZE (CONFIG_SRAM_SIZE * 1K)
    #define RAM_ADDR CONFIG_SRAM_BASE_ADDRESS
  #endif
#else
  #define RAM_SIZE (CONFIG_SRAM_SIZE * 1K - CONFIG_BOOTLOADER_SRAM_SIZE * 1K)
  #define RAM_ADDR CONFIG_SRAM_BASE_ADDRESS
#endif

/* Set alignment to CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE
 * to make linker section alignment comply with MPU granularity.
 */
#if defined(CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE)
_region_min_align = CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE;
#elif defined(CONFIG_ARM_AARCH32_MMU)
_region_min_align = CONFIG_MMU_PAGE_SIZE;
#else
/* If building without MPU/MMU support, use default 4-byte alignment. */
_region_min_align = 4;
#endif

#if defined(CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT)
  #define MPU_ALIGN(region_size) \
    . = ALIGN(_region_min_align); \
    . = ALIGN(1 << LOG2CEIL(region_size))
#else
  #define MPU_ALIGN(region_size) \
    . = ALIGN(_region_min_align)
#endif

#define BSS_ALIGN ALIGN(_region_min_align)

MEMORY
{
    FLASH    (rx) : ORIGIN = ROM_ADDR, LENGTH = ROM_SIZE
    SRAM     (wx) : ORIGIN = RAM_ADDR, LENGTH = RAM_SIZE
    LINKER_DT_REGION_FROM_NODE(DT_CHOSEN(zephyr_ocm), rw)
    /* Used by and documented in include/linker/intlist.ld */
    IDT_LIST (wx) : ORIGIN = 0xFFFFF7FF, LENGTH = 2K
}

ENTRY(CONFIG_KERNEL_ENTRY)

SECTIONS
{
#include <linker/rel-sections.ld>

    /*
     * .plt and .iplt are here according to 'arm-zephyr-elf-ld --verbose',
     * before text section.
     */
    SECTION_PROLOGUE(.plt,,)
    {
        *(.plt)
    }

    SECTION_PROLOGUE(.iplt,,)
    {
        *(.iplt)
    }

    GROUP_START(ROMABLE_REGION)

#if defined(CONFIG_XIP)
    __rom_region_start = ROM_ADDR;
#else
    __rom_region_start = RAM_ADDR;
#endif

    SECTION_PROLOGUE(rom_start,,)
    {

/* Located in generated directory. This file is populated by calling
 * zephyr_linker_sources(ROM_START ...). This typically contains the vector
 * table and debug information.
 */
#include <snippets-rom-start.ld>

    } GROUP_LINK_IN(ROMABLE_REGION)

#ifdef CONFIG_CODE_DATA_RELOCATION

#include <linker_relocate.ld>

#endif /* CONFIG_CODE_DATA_RELOCATION */

    SECTION_PROLOGUE(_TEXT_SECTION_NAME,,)
    {
        . = ALIGN(_region_min_align);
        __text_region_start = .;
#ifndef CONFIG_XIP
        z_mapped_start = .;
#endif

#include <linker/kobject-text.ld>

        *(.text)
        *(".text.*")
        *(.gnu.linkonce.t.*)

        /*
         * These are here according to 'arm-zephyr-elf-ld --verbose',
         * after .gnu.linkonce.t.*
         */
        *(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx)

        __text_region_end = .;
        . = ALIGN(_region_min_align);
    } GROUP_LINK_IN(ROMABLE_REGION)

#if defined (CONFIG_CPLUSPLUS)
    SECTION_PROLOGUE(.ARM.extab,,)
    {
        /*
         * .ARM.extab section containing exception unwinding information.
         */
        *(.ARM.extab* .gnu.linkonce.armextab.*)
    } GROUP_LINK_IN(ROMABLE_REGION)
#endif

    SECTION_PROLOGUE(.ARM.exidx,,)
    {
        /*
         * This section, related to stack and exception unwinding, is placed
         * explicitly to prevent it from being shared between multiple regions.
         * It  must be defined for gcc to support 64-bit math and avoid
         * section overlap.
         */
        __exidx_start = .;
#if defined (__GCC_LINKER_CMD__)
        *(.ARM.exidx* gnu.linkonce.armexidx.*)
#endif
        __exidx_end = .;
    } GROUP_LINK_IN(ROMABLE_REGION)

    SECTION_PROLOGUE(rodata_start,,)
    {
        . = ALIGN(_region_min_align);
        __rodata_region_start = .;
    } GROUP_LINK_IN(ROMABLE_REGION)

#include <linker/common-rom.ld>
#include <linker/thread-local-storage.ld>
#include <linker/cplusplus-rom.ld>

    SECTION_PROLOGUE(_RODATA_SECTION_NAME,,)
    {
        *(.rodata)
        *(".rodata.*")
        *(.gnu.linkonce.r.*)

/* Located in generated directory. This file is populated by the
 * zephyr_linker_sources() Cmake function.
 */
#include <snippets-rodata.ld>

#include <linker/kobject-rom.ld>

        /*
         * For XIP images, in order to avoid the situation when __data_rom_start
         * is 32-bit aligned, but the actual data is placed right after rodata
         * section, which may not end exactly at 32-bit border, pad rodata
         * section, so __data_rom_start points at data and it is 32-bit aligned.
         *
         * On non-XIP images this may enlarge image size up to 3 bytes. This
         * generally is not an issue, since modern ROM and FLASH memory is
         * usually 4k aligned.
         */
        . = ALIGN(4);

        /*
         * RODATA must be the last section so that the size of the entire read
         * only area will be filled to a power of 2.
         */
        MPU_ALIGN(ABSOLUTE(.) - __rom_region_start);
    } GROUP_LINK_IN(ROMABLE_REGION)

    __rodata_region_end = .;
    __rom_region_end = .;
    MPU_ALIGN(__rodata_region_end - __rom_region_start);
    _image_rom_end_order = (LOG2CEIL(__rom_region_end) - 1) << 1;

    GROUP_END(ROMABLE_REGION)

    /*
     * These are here according to 'arm-zephyr-elf-ld --verbose',
     * before data section.
     */
    SECTION_PROLOGUE(.got,,)
    {
        *(.got.plt)
        *(.igot.plt)
        *(.got)
        *(.igot)
    }

    GROUP_START(RAMABLE_REGION)

    . = RAM_ADDR;
    /* Align the start of image SRAM with the
     * minimum granularity required by MPU.
     */
    . = ALIGN(_region_min_align);
    _image_ram_start = .;
#ifdef CONFIG_XIP
    z_mapped_start = .;
#endif

/* Located in generated directory. This file is populated by the
 * zephyr_linker_sources() Cmake function.
 */
#include <snippets-ram-sections.ld>

#if defined(CONFIG_USERSPACE)
#define APP_SHARED_ALIGN . = ALIGN(_region_min_align);
#define SMEM_PARTITION_ALIGN MPU_ALIGN

#include <app_smem.ld>

    _app_smem_size = _app_smem_end - _app_smem_start;
    _app_smem_rom_start = LOADADDR(_APP_SMEM_SECTION_NAME);
#endif  /* CONFIG_USERSPACE */

    SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD), BSS_ALIGN)
    {
        /*
         * For performance, BSS section is assumed to be 4 byte aligned and
         * a multiple of 4 bytes
         */
        . = ALIGN(4);
        __bss_start = .;
        __kernel_ram_start = .;

        *(.bss)
        *(".bss.*")
        *(COMMON)
        *(".kernel_bss.*")

#ifdef CONFIG_CODE_DATA_RELOCATION
#include <linker_sram_bss_relocate.ld>
#endif

        /*
         * As memory is cleared in words only, it is simpler to ensure the BSS
         * section ends on a 4 byte boundary. This wastes a maximum of 3 bytes.
         */
        __bss_end = ALIGN(4);
    } GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION)

#include <linker/common-noinit.ld>

    SECTION_DATA_PROLOGUE(_DATA_SECTION_NAME,,)
    {
        __data_region_start = .;
        __data_start = .;
        *(.data)
        *(".data.*")
        *(".kernel.*")

/* Located in generated directory. This file is populated by the
 * zephyr_linker_sources() Cmake function.
 */
#include <snippets-rwdata.ld>

#ifdef CONFIG_CODE_DATA_RELOCATION
#include <linker_sram_data_relocate.ld>
#endif
        __data_end = .;

    } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
    __data_size = __data_end - __data_start;
    __data_load_start = LOADADDR(_DATA_SECTION_NAME);

    __data_region_load_start = LOADADDR(_DATA_SECTION_NAME);

#include <linker/common-ram.ld>
#include <linker/kobject-data.ld>
#include <linker/cplusplus-ram.ld>

/* Located in generated directory. This file is populated by the
 * zephyr_linker_sources() Cmake function.
 */
#include <snippets-data-sections.ld>

    __data_region_end = .;

    /* Define linker symbols */

    . = ALIGN(_region_min_align);
    _image_ram_end = .;
    _end = .; /* end of image */
    z_mapped_end = .;

    __kernel_ram_end = RAM_ADDR + RAM_SIZE;
    __kernel_ram_size = __kernel_ram_end - __kernel_ram_start;

    GROUP_END(RAMABLE_REGION)

#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_ocm), okay)
GROUP_START(OCM)

	SECTION_PROLOGUE(_OCM_BSS_SECTION_NAME, (NOLOAD),SUBALIGN(4))
	{
		__ocm_start = .;
		__ocm_bss_start = .;
		*(.ocm_bss)
		*(".ocm_bss.*")
		__ocm_bss_end = .;
	} GROUP_LINK_IN(LINKER_DT_NODE_REGION_NAME(DT_CHOSEN(zephyr_ocm)))

	SECTION_PROLOGUE(_OCM_DATA_SECTION_NAME,,SUBALIGN(4))
	{
		__ocm_data_start = .;
		*(.ocm_data)
		*(".ocm_data.*")
		__ocm_data_end = .;
	} GROUP_LINK_IN(LINKER_DT_NODE_REGION_NAME(DT_CHOSEN(zephyr_ocm)))

  __ocm_end = .;
  __ocm_size = __ocm_end - __ocm_start;

GROUP_END(OCM)
#endif

/* Located in generated directory. This file is populated by the
 * zephyr_linker_sources() Cmake function.
 */
#include <snippets-sections.ld>

#include <linker/debug-sections.ld>

    SECTION_PROLOGUE(.ARM.attributes, 0,)
    {
        KEEP(*(.ARM.attributes))
        KEEP(*(.gnu.attributes))
    }

    /* Must be last in romable region */
    SECTION_PROLOGUE(.last_section,(NOLOAD),)
    {
    } GROUP_LINK_IN(ROMABLE_REGION)

    /* To provide the image size as a const expression,
     * calculate this value here. */
    _flash_used = LOADADDR(.last_section) - __rom_region_start;

}

/*
 * Copyright (c) 2013-2014 Wind River Systems, Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file
 * @brief Linker command/script file
 *
 * Linker script for the Cortex-A and Cortex-R platforms.
 */

#include <autoconf.h>
#include <linker/sections.h>
#include <devicetree.h>

#include <linker/devicetree_regions.h>
#include <linker/linker-defs.h>
#include <linker/linker-tool.h>

/* physical address of RAM */
#ifdef CONFIG_XIP
  #define ROMABLE_REGION FLASH
  #define RAMABLE_REGION SRAM
#else
  #define ROMABLE_REGION SRAM
  #define RAMABLE_REGION SRAM
#endif

#if !defined(CONFIG_XIP) && (CONFIG_FLASH_SIZE == 0)
  #define ROM_ADDR RAM_ADDR
#else
  #define ROM_ADDR (CONFIG_FLASH_BASE_ADDRESS + CONFIG_FLASH_LOAD_OFFSET)
#endif

#if CONFIG_FLASH_LOAD_SIZE > 0
  #define ROM_SIZE CONFIG_FLASH_LOAD_SIZE
#else
  #define ROM_SIZE (CONFIG_FLASH_SIZE*1K - CONFIG_FLASH_LOAD_OFFSET)
#endif

#if defined(CONFIG_XIP)
  #if defined(CONFIG_IS_BOOTLOADER)
    #define RAM_SIZE (CONFIG_BOOTLOADER_SRAM_SIZE * 1K)
    #define RAM_ADDR (CONFIG_SRAM_BASE_ADDRESS + \
                     (CONFIG_SRAM_SIZE * 1K - RAM_SIZE))
  #else
    #define RAM_SIZE (CONFIG_SRAM_SIZE * 1K)
    #define RAM_ADDR CONFIG_SRAM_BASE_ADDRESS
  #endif
#else
  #define RAM_SIZE (CONFIG_SRAM_SIZE * 1K - CONFIG_BOOTLOADER_SRAM_SIZE * 1K)
  #define RAM_ADDR CONFIG_SRAM_BASE_ADDRESS
#endif

/* Set alignment to CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE
 * to make linker section alignment comply with MPU granularity.
 */
#if defined(CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE)
_region_min_align = CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE;
#elif defined(CONFIG_ARM_AARCH32_MMU)
_region_min_align = CONFIG_MMU_PAGE_SIZE;
#else
/* If building without MPU support, use default 4-byte alignment. */
_region_min_align = 4;
#endif

#if defined(CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT)
  #define MPU_ALIGN(region_size) \
    . = ALIGN(_region_min_align); \
    . = ALIGN(1 << LOG2CEIL(region_size))
#else
  #define MPU_ALIGN(region_size) \
    . = ALIGN(_region_min_align)
#endif

#define BSS_ALIGN ALIGN(_region_min_align)

MEMORY
{
    FLASH    (rx) : ORIGIN = ROM_ADDR, LENGTH = ROM_SIZE
    SRAM     (wx) : ORIGIN = RAM_ADDR, LENGTH = RAM_SIZE
    LINKER_DT_REGION_FROM_NODE(DT_CHOSEN(zephyr_ocm), rw)
    /* Used by and documented in include/linker/intlist.ld */
    IDT_LIST (wx) : ORIGIN = 0xFFFFF7FF, LENGTH = 2K
}

ENTRY(CONFIG_KERNEL_ENTRY)

SECTIONS
{
#include <linker/rel-sections.ld>

    /*
     * .plt and .iplt are here according to 'arm-zephyr-elf-ld --verbose',
     * before text section.
     */
    SECTION_PROLOGUE(.plt,,)
    {
        *(.plt)
    }

    SECTION_PROLOGUE(.iplt,,)
    {
        *(.iplt)
    }

    GROUP_START(ROMABLE_REGION)

#if defined(CONFIG_XIP)
    __rom_region_start = ROM_ADDR;
#else
    __rom_region_start = RAM_ADDR;
#endif

    SECTION_PROLOGUE(rom_start,,)
    {

/* Located in generated directory. This file is populated by calling
 * zephyr_linker_sources(ROM_START ...). This typically contains the vector
 * table and debug information.
 */
#include <snippets-rom-start.ld>

    } GROUP_LINK_IN(ROMABLE_REGION)

#ifdef CONFIG_CODE_DATA_RELOCATION

#include <linker_relocate.ld>

#endif /* CONFIG_CODE_DATA_RELOCATION */

    SECTION_PROLOGUE(_TEXT_SECTION_NAME,,)
    {
        . = ALIGN(_region_min_align);
        __text_region_start = .;
#ifndef CONFIG_XIP
        z_mapped_start = .;
#endif

#include <linker/kobject-text.ld>

        *(.text)
        *(".text.*")
        *(.gnu.linkonce.t.*)

        /*
         * These are here according to 'arm-zephyr-elf-ld --verbose',
         * after .gnu.linkonce.t.*
         */
        *(.glue_7t) *(.glue_7) *(.vfp11_veneer) *(.v4_bx)

    } GROUP_LINK_IN(ROMABLE_REGION)

    __text_region_end = .;
    . = ALIGN(_region_min_align);

#if defined (CONFIG_CPLUSPLUS)
    SECTION_PROLOGUE(.ARM.extab,,)
    {
        /*
         * .ARM.extab section containing exception unwinding information.
         */
        *(.ARM.extab* .gnu.linkonce.armextab.*)
    } GROUP_LINK_IN(ROMABLE_REGION)
#endif

    SECTION_PROLOGUE(.ARM.exidx,,)
    {
        /*
         * This section, related to stack and exception unwinding, is placed
         * explicitly to prevent it from being shared between multiple regions.
         * It  must be defined for gcc to support 64-bit math and avoid
         * section overlap.
         */
        __exidx_start = .;
#if defined (__GCC_LINKER_CMD__)
        *(.ARM.exidx* gnu.linkonce.armexidx.*)
#endif
        __exidx_end = .;
    } GROUP_LINK_IN(ROMABLE_REGION)

    . = ALIGN(_region_min_align);
    __rodata_region_start = .;

#include <linker/common-rom.ld>
#include <linker/thread-local-storage.ld>
#include <linker/cplusplus-rom.ld>

    SECTION_PROLOGUE(_RODATA_SECTION_NAME,,)
    {
        *(.rodata)
        *(".rodata.*")
        *(.gnu.linkonce.r.*)

/* Located in generated directory. This file is populated by the
 * zephyr_linker_sources() Cmake function.
 */
#include <snippets-rodata.ld>

#include <linker/kobject-rom.ld>

        /*
         * For XIP images, in order to avoid the situation when __data_rom_start
         * is 32-bit aligned, but the actual data is placed right after rodata
         * section, which may not end exactly at 32-bit border, pad rodata
         * section, so __data_rom_start points at data and it is 32-bit aligned.
         *
         * On non-XIP images this may enlarge image size up to 3 bytes. This
         * generally is not an issue, since modern ROM and FLASH memory is
         * usually 4k aligned.
         */
        . = ALIGN(4);

        /*
         * RODATA must be the last section so that the size of the entire read
         * only area will be filled to a power of 2.
         */
        MPU_ALIGN(ABSOLUTE(.) - __rom_region_start);
    } GROUP_LINK_IN(ROMABLE_REGION)

    __rodata_region_end = .;
    __rom_region_end = .;
    MPU_ALIGN(__rodata_region_end - __rom_region_start);
    _image_rom_end_order = (LOG2CEIL(__rom_region_end) - 1) << 1;

    GROUP_END(ROMABLE_REGION)

    /*
     * These are here according to 'arm-zephyr-elf-ld --verbose',
     * before data section.
     */
    SECTION_PROLOGUE(.got,,)
    {
        *(.got.plt)
        *(.igot.plt)
        *(.got)
        *(.igot)
    }

    GROUP_START(RAMABLE_REGION)

    . = RAM_ADDR;
    /* Align the start of image SRAM with the
     * minimum granularity required by MPU.
     */
    . = ALIGN(_region_min_align);
    _image_ram_start = .;
#ifdef CONFIG_XIP
    z_mapped_start = .;
#endif

/* Located in generated directory. This file is populated by the
 * zephyr_linker_sources() Cmake function.
 */
#include <snippets-ram-sections.ld>

#if defined(CONFIG_USERSPACE)
#define APP_SHARED_ALIGN . = ALIGN(_region_min_align);
#define SMEM_PARTITION_ALIGN MPU_ALIGN

#include <app_smem.ld>

    _app_smem_size = _app_smem_end - _app_smem_start;
    _app_smem_rom_start = LOADADDR(_APP_SMEM_SECTION_NAME);
#endif  /* CONFIG_USERSPACE */

    SECTION_DATA_PROLOGUE(_BSS_SECTION_NAME,(NOLOAD), BSS_ALIGN)
    {
        /*
         * For performance, BSS section is assumed to be 4 byte aligned and
         * a multiple of 4 bytes
         */
        . = ALIGN(4);
        __bss_start = .;
        __kernel_ram_start = .;

        *(.bss)
        *(".bss.*")
        *(COMMON)
        *(".kernel_bss.*")

#ifdef CONFIG_CODE_DATA_RELOCATION
#include <linker_sram_bss_relocate.ld>
#endif

        /*
         * As memory is cleared in words only, it is simpler to ensure the BSS
         * section ends on a 4 byte boundary. This wastes a maximum of 3 bytes.
         */
        __bss_end = ALIGN(4);
    } GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION)

#include <linker/common-noinit.ld>

    SECTION_DATA_PROLOGUE(_DATA_SECTION_NAME,,)
    {
        __data_region_start = .;
        __data_start = .;
        *(.data)
        *(".data.*")
        *(".kernel.*")

/* Located in generated directory. This file is populated by the
 * zephyr_linker_sources() Cmake function.
 */
#include <snippets-rwdata.ld>

#ifdef CONFIG_CODE_DATA_RELOCATION
#include <linker_sram_data_relocate.ld>
#endif
        __data_end = .;

    } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION)
    __data_size = __data_end - __data_start;
    __data_load_start = LOADADDR(_DATA_SECTION_NAME);

    __data_region_load_start = LOADADDR(_DATA_SECTION_NAME);

#include <linker/common-ram.ld>
#include <linker/kobject-data.ld>
#include <linker/cplusplus-ram.ld>

/* Located in generated directory. This file is populated by the
 * zephyr_linker_sources() Cmake function.
 */
#include <snippets-data-sections.ld>

    __data_region_end = .;

    /* Define linker symbols */

    . = ALIGN(_region_min_align);
    _image_ram_end = .;
    _end = .; /* end of image */
    z_mapped_end = .;

    __kernel_ram_end = RAM_ADDR + RAM_SIZE;
    __kernel_ram_size = __kernel_ram_end - __kernel_ram_start;

    GROUP_END(RAMABLE_REGION)

#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_ocm), okay)
GROUP_START(OCM)

	SECTION_PROLOGUE(_OCM_BSS_SECTION_NAME, (NOLOAD),SUBALIGN(4))
	{
		__ocm_start = .;
		__ocm_bss_start = .;
		*(.ocm_bss)
		*(".ocm_bss.*")
		__ocm_bss_end = .;
	} GROUP_LINK_IN(LINKER_DT_NODE_REGION_NAME(DT_CHOSEN(zephyr_ocm)))

	SECTION_PROLOGUE(_OCM_DATA_SECTION_NAME,,SUBALIGN(4))
	{
		__ocm_data_start = .;
		*(.ocm_data)
		*(".ocm_data.*")
		__ocm_data_end = .;
	} GROUP_LINK_IN(LINKER_DT_NODE_REGION_NAME(DT_CHOSEN(zephyr_ocm)))

  __ocm_end = .;
  __ocm_size = __ocm_end - __ocm_start;

GROUP_END(OCM)
#endif

/* Located in generated directory. This file is populated by the
 * zephyr_linker_sources() Cmake function.
 */
#include <snippets-sections.ld>

#include <linker/debug-sections.ld>

    SECTION_PROLOGUE(.ARM.attributes, 0,)
    {
        KEEP(*(.ARM.attributes))
        KEEP(*(.gnu.attributes))
    }

    /* Must be last in romable region */
    SECTION_PROLOGUE(.last_section,(NOLOAD),)
    {
    } GROUP_LINK_IN(ROMABLE_REGION)

    /* To provide the image size as a const expression,
     * calculate this value here. */
    _flash_used = LOADADDR(.last_section) - __rom_region_start;

}


linker: more .rel for orphan sections

linker: more .rel for orphan sections

There are sections defined in common-rom/ram.ld where they are
showing up as orphan sections. So add these as known sections.

Fixes #10493

Signed-off-by: Daniel Leung <d94e04d205b5962d7873a139ef298b03c1717f72@intel.com>

	/*
	 * .rel.* are for relocation.
	 * These are being produced by compiler/linker.
	 * Specify these here so they are not considered orphan sections.
	 *
	 * Obtained via
	 * '$(ARCH)-zephyr-elf-ld --verbose'
	 */

#if !defined(CONFIG_RISCV32) && !defined(CONFIG_XTENSA)
	SECTION_PROLOGUE(.rel.dyn,,)
	{
	*(.rel.init)
	*(.rel.text .rel.text.* .rel.text_start.* .rel.gnu.linkonce.t.*)
	*(.rel.fini)
	*(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
	*(.rel.data.rel.ro .rel.data.rel.ro.* .rel.gnu.linkonce.d.rel.ro.*)
	*(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
	*(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
	*(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)

#if defined(CONFIG_ARCH_POSIX)
	*(.rel.preinit_array)
	*(.rel.init_array)
	*(.rel.fini_array)
#endif

	*(.rel.ctors)
	*(.rel.dtors)
	*(.rel.got)
	*(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)

#if defined(CONFIG_ARM) || defined(CONFIG_NIOS2)
	PROVIDE_HIDDEN (__rel_iplt_start = .);
	*(.rel.iplt)
	PROVIDE_HIDDEN (__rel_iplt_end = .);
#endif

	/* These are related to sections defined by Zephyr */
	*(.rel.kernel .rel.kernel.*)
	*(.rel.init_PRE_KERNEL*)
	*(.rel.init_POST_KERNEL*)
	*(.rel.init_APPLICATION*)

#if defined(CONFIG_ARCH_POSIX)
	*(.rel.native_PRE_BOOT*)
	*(.rel.native_FIRST_SLEEP*)
	*(.rel.native_ON_EXIT*)
#endif

	*(.rel.devconfig.*)

	*(.rel._k_*)

	*(.rel._bt_settings.*)

	*(.rel.log_*)

	*(.rel._net_buf_pool.*)
	*(.rel.net_*)

	*(.rel._static_thread_data.*)

	*(.rel.usb.*)

#if defined(CONFIG_X86)
	*(.rel.ifunc)
	*(.rel.mmulist)
	*(.rel.tss)
#endif
	}
#endif /* !defined(CONFIG_RISCV32) */

#if defined(CONFIG_ARM) || defined(CONFIG_NIOS2) || defined(CONFIG_RISCV32)
	SECTION_PROLOGUE(.rela.dyn,,)
	{
	*(.rela.init)
	*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
	*(.rela.fini)
	*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
	*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
	*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
	*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
	*(.rela.ctors)
	*(.rela.dtors)
	*(.rela.got)
	*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)

#if defined(CONFIG_ARM) || defined(CONFIG_NIOS2)
	PROVIDE_HIDDEN (__rela_iplt_start = .);
	*(.rela.iplt)
	PROVIDE_HIDDEN (__rela_iplt_end = .);
#endif

	/* These are related to sections defined by Zephyr */
	*(.rela.kernel .rel.kernel.*)
	*(.rela.init_PRE_KERNEL*)
	*(.rela.init_POST_KERNEL*)
	*(.rela.init_APPLICATION*)

	*(.rela.devconfig.*)

	*(.rela._k_*)

	*(.rela._bt_settings.*)

	*(.rela.log_*)

	*(.rela._net_buf_pool.*)
	*(.rela.net_*)

	*(.rela._static_thread_data.*)

	*(.rela.usb.*)

#if defined(CONFIG_RISCV32)
	*(.rela.exception.*)
	*(.rela.gnu.linkonce.sw_isr_table)
	*(.rela.sdata.*)
#endif

	}
#endif

#if !defined(CONFIG_RISCV32) && !defined(CONFIG_XTENSA)
	SECTION_PROLOGUE(.rel.plt,,)
	{
	*(.rel.plt)

#if defined(CONFIG_X86)
	PROVIDE_HIDDEN (__rel_iplt_start = .);
	*(.rel.iplt)
	PROVIDE_HIDDEN (__rel_iplt_end = .);
#endif
	}
#endif /* !defined(CONFIG_RISCV32) */

#if defined(CONFIG_ARM) || defined(CONFIG_NIOS2) || defined(CONFIG_RISCV32)
	SECTION_PROLOGUE(.rela.plt,,)
	{
	*(.rela.plt)
	}
#endif

	/*
	 * .rel.* are for relocation.
	 * These are being produced by compiler/linker.
	 * Specify these here so they are not considered orphan sections.
	 *
	 * Obtained via
	 * '$(ARCH)-zephyr-elf-ld --verbose'
	 */

#if !defined(CONFIG_RISCV32) && !defined(CONFIG_XTENSA)
	SECTION_PROLOGUE(.rel.dyn,,)
	{
	*(.rel.init)
	*(.rel.text .rel.text.* .rel.text_start.* .rel.gnu.linkonce.t.*)
	*(.rel.fini)
	*(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
	*(.rel.data.rel.ro .rel.data.rel.ro.* .rel.gnu.linkonce.d.rel.ro.*)
	*(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
	*(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
	*(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)

#if defined(CONFIG_ARCH_POSIX)
	*(.rel.preinit_array)
	*(.rel.init_array)
	*(.rel.fini_array)
#endif

	*(.rel.ctors)
	*(.rel.dtors)
	*(.rel.got)
	*(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)

#if defined(CONFIG_ARM) || defined(CONFIG_NIOS2)
	PROVIDE_HIDDEN (__rel_iplt_start = .);
	*(.rel.iplt)
	PROVIDE_HIDDEN (__rel_iplt_end = .);
#endif

	/* These are related to sections defined by Zephyr */
	*(.rel.kernel .rel.kernel.*)
	*(.rel.init_PRE_KERNEL*)
	*(.rel.init_POST_KERNEL*)
	*(.rel.init_APPLICATION*)

#if defined(CONFIG_ARCH_POSIX)
	*(.rel.native_PRE_BOOT*)
	*(.rel.native_FIRST_SLEEP*)
	*(.rel.native_ON_EXIT*)
#endif

	*(.rel.devconfig.*)
	*(.rel._k_alert.*)
	*(.rel._k_mem_pool.*)
	*(.rel._k_timer.*)
	*(.rel._static_thread_data.*)

#if defined(CONFIG_X86)
	*(.rel.ifunc)
	*(.rel.mmulist)
	*(.rel.tss)
#endif
	}
#endif /* !defined(CONFIG_RISCV32) */

#if defined(CONFIG_ARM) || defined(CONFIG_NIOS2) || defined(CONFIG_RISCV32)
	SECTION_PROLOGUE(.rela.dyn,,)
	{
	*(.rela.init)
	*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
	*(.rela.fini)
	*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
	*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
	*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
	*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
	*(.rela.ctors)
	*(.rela.dtors)
	*(.rela.got)
	*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)

#if defined(CONFIG_ARM) || defined(CONFIG_NIOS2)
	PROVIDE_HIDDEN (__rela_iplt_start = .);
	*(.rela.iplt)
	PROVIDE_HIDDEN (__rela_iplt_end = .);
#endif

	/* These are related to sections defined by Zephyr */
	*(.rela.kernel .rel.kernel.*)
	*(.rela.init_PRE_KERNEL*)
	*(.rela.init_POST_KERNEL*)
	*(.rela.init_APPLICATION*)
	*(.rela._k_alert.*)
	*(.rela._k_mem_pool.*)
	*(.rela._k_timer.*)
	*(.rela._static_thread_data.*)

#if defined(CONFIG_RISCV32)
	*(.rela.devconfig.*)
	*(.rela.exception.*)
	*(.rela.gnu.linkonce.sw_isr_table)
	*(.rela.sdata.*)
#endif

	}
#endif

#if !defined(CONFIG_RISCV32) && !defined(CONFIG_XTENSA)
	SECTION_PROLOGUE(.rel.plt,,)
	{
	*(.rel.plt)

#if defined(CONFIG_X86)
	PROVIDE_HIDDEN (__rel_iplt_start = .);
	*(.rel.iplt)
	PROVIDE_HIDDEN (__rel_iplt_end = .);
#endif
	}
#endif /* !defined(CONFIG_RISCV32) */

#if defined(CONFIG_ARM) || defined(CONFIG_NIOS2) || defined(CONFIG_RISCV32)
	SECTION_PROLOGUE(.rela.plt,,)
	{
	*(.rela.plt)
	}
#endif