blob: 127ed82a2f90824bef9b697b68a28bc66bf52f93 [file]
/* Copyright 2021 The TensorFlow Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
OUTPUT(a.elf)
/* By default, program starts from reset address (the default location of the interrupt table) */
ENTRY(__cxd_inttbl_start)
/** Memory configuration parameters.
* The parameters become application symbols and can be referred from application
*/
__internal_code_start = DEFINED(__internal_code_start) ? __internal_code_start : 0x00000000;
__internal_code_size = DEFINED(__internal_code_size ) ? __internal_code_size : 256k;
__internal_data_start = DEFINED(__internal_data_start) ? __internal_data_start : 0x00000000;
__internal_data_size = DEFINED(__internal_data_size ) ? __internal_data_size : 512k;
__external_start = DEFINED(__external_start ) ? __external_start : 0x40000000;
__external_size = DEFINED(__external_size ) ? __external_size : 0x40000000;
__rom_start = DEFINED(__rom_start ) ? __rom_start : 0xC0000000;
__rom_size = DEFINED(__rom_size ) ? __rom_size : 1024M;
__malloc_size = DEFINED(__malloc_size ) ? __malloc_size : 32k;
__stack_size = DEFINED(__stack_size ) ? __stack_size : 32k;
__arg_sect_size = DEFINED(__arg_sect_size ) ? __arg_sect_size : 512;
MEMORY {
INTERNAL_CODE (rx) : ORIGIN = __internal_code_start, LENGTH = __internal_code_size
INTERNAL_DATA (rw) : ORIGIN = __internal_data_start, LENGTH = __internal_data_size
EXTERNAL (rwx) : ORIGIN = __external_start , LENGTH = __external_size
ROM (rx) : ORIGIN = __rom_start , LENGTH = __rom_size
}
SECTIONS {
.inttbl : ALIGN(0x20) {
/** The interrupt vector table. Contains the NMI
* and maskable interrupt handlers
*/
. = 0x0;
KEEP(*(.inttbl))
. = ALIGN(0x20);
KEEP(*(.sinttbl))
} >INTERNAL_CODE
.data.internal : ALIGN(0x20) {
PROVIDE(__data_internal_start = ABSOLUTE(.));
/* Don't map any data at address zero to avoid issues with C NULL
* pointer checks
*/
. += 0x4;
PROVIDE(__data_start = ABSOLUTE(.));
*(.data .data.*)
PROVIDE(__data_end = ABSOLUTE(.));
PROVIDE(__data_size = ABSOLUTE(+__data_end - __data_start));
PROVIDE(__sdata_start = ABSOLUTE(.));
*(.sdata .sdata.*)
PROVIDE(__sdata_end = ABSOLUTE(.));
PROVIDE(__sdata_size = ABSOLUTE(+__sdata_end - __sdata_start));
PROVIDE(__data_internal_end = ABSOLUTE(.));
PROVIDE(__data_internal_size = ABSOLUTE(__data_internal_end - __data_internal_start));
} >INTERNAL_DATA
.data.internal.clone (NOLOAD) : ALIGN(0x20) {
PROVIDE(__data_internal_clone_start = ABSOLUTE(.));
. = ABSOLUTE(. + __data_internal_size);
} >INTERNAL_DATA
.data.internal.ro : ALIGN(0x20) {
PROVIDE(__data_internal_ro_start = ABSOLUTE(.));
PROVIDE(__rodata_start = ABSOLUTE(.));
*(.rodata .rodata.*)
PROVIDE(__rodata_end = ABSOLUTE(.));
PROVIDE(__rodata_size = ABSOLUTE(+__rodata_end - __rodata_start));
PROVIDE(__data_internal_ro_end = ABSOLUTE(.));
PROVIDE(__data_internal_ro_size = ABSOLUTE(__data_internal_ro_end - __data_internal_ro_start));
} >INTERNAL_DATA
.cst.call : ALIGN(4) {
PROVIDE(__cst_call_start = ABSOLUTE(.));
*(.cst.call)
PROVIDE(__cst_call_end = ABSOLUTE(.));
} >INTERNAL_DATA
.cst.mov : ALIGN(4) {
PROVIDE(__cst_mov_start = ABSOLUTE(.));
*(.cst.mov)
PROVIDE(__cst_mov_end = ABSOLUTE(.));
} >INTERNAL_DATA
.bss (NOLOAD) : ALIGN(0x20) {
PROVIDE(__bss_start = ABSOLUTE(.));
*(.bss .bss.*)
PROVIDE(__common_start = ABSOLUTE(.));
*(COMMON)
PROVIDE(__common_end = ABSOLUTE(.));
PROVIDE(__common_size = ABSOLUTE(+__common_end - __common_start));
PROVIDE(__bss_end = ABSOLUTE(.));
PROVIDE(__bss_size = ABSOLUTE(+__bss_end - __bss_start));
} >INTERNAL_DATA
__STACK_SECT (NOLOAD) : ALIGN(0x10) {
__stack_start = ABSOLUTE(.);
. = . + __stack_size;
__stack_end = ABSOLUTE(.);
} >INTERNAL_DATA
.text : ALIGN(0x20) {
PROVIDE(__text_start = ABSOLUTE(.));
/* The __call_saved* functions need to be placed at low addresses for
* calling with absolute call instructions
*/
*(.text.__call_saved*)
*(.text .text.*)
PROVIDE(__text_end = ABSOLUTE(.));
} >EXTERNAL
.data.external : ALIGN(0x20) {
/** .data1, .rodata1, .sdata1 are all for large symbols which cannot
* fit in limited internal memory. We put them in external memory by
* default. */
PROVIDE(__data_external_start = ABSOLUTE(.));
PROVIDE(__data1_start = ABSOLUTE(.));
*(.data1 .data1.*)
PROVIDE(__data1_end = ABSOLUTE(.));
PROVIDE(__sdata1_start = ABSOLUTE(.));
*(.sdata1 .sdata1.*)
PROVIDE(__sdata1_end = ABSOLUTE(.));
PROVIDE(__sdata1_size = ABSOLUTE(+__sdata1_end - __sdata1_start));
PROVIDE(__data_external_end = ABSOLUTE(.));
PROVIDE(__data_external_size = ABSOLUTE(__data_external_end - __data_external_start));
} >EXTERNAL
.data.external.clone (NOLOAD) : ALIGN(0x20) {
PROVIDE(__data_external_clone_start = ABSOLUTE(.));
. = ABSOLUTE(. + __data_external_size);
} >EXTERNAL
.data.external.ro : ALIGN(0x20) {
/** .data1, .rodata1, .sdata1 are all for large symbols which cannot
* fit in limited internal memory. We put them in external memory by
* default. */
PROVIDE(__data_external_ro_start = ABSOLUTE(.));
PROVIDE(__rodata1_start = ABSOLUTE(.));
*(.rodata1 .rodata1.*)
PROVIDE(__rodata1_end = ABSOLUTE(.));
PROVIDE(__rodata1_size = ABSOLUTE(+__rodata1_end - __rodata1_start));
/* Constructors and destructors are called once per program invocation,
* so are never in the hot path; they shouldn't waste space in limited
* internal memory so we place them in slower, external memory */
. = ALIGN(4); /* constructors must be aligned on a word boundary */
PROVIDE(__init_array_start = ABSOLUTE(.));
KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)));
KEEP(*(SORT_BY_INIT_PRIORITY(.init_array*) SORT_BY_INIT_PRIORITY(.ctors*)));
PROVIDE(__init_array_end = ABSOLUTE(.));
PROVIDE(__fini_array_start = ABSOLUTE(.));
/* destructors are run in reverse order of their priority */
KEEP(*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)));
KEEP(*(SORT_BY_INIT_PRIORITY(.fini_array*) SORT_BY_INIT_PRIORITY(.dtors*)));
PROVIDE(__fini_array_end = ABSOLUTE(.));
PROVIDE(__data_external_ro_end = ABSOLUTE(.));
PROVIDE(__data_external_ro_size = ABSOLUTE(__data_external_ro_end - __data_external_ro_start));
} >EXTERNAL
.bss1 (NOLOAD) : ALIGN(0x20) {
/**
* `.bss1` is for large zero-initialized symbols that do not fit in
* internal data
*/
PROVIDE(__bss1_start = ABSOLUTE(.));
*(.bss1 .bss1.*)
PROVIDE(__large_common_start = ABSOLUTE(.));
*(LARGE_COMMON)
PROVIDE(__large_common_end = ABSOLUTE(.));
PROVIDE(__large_common_size = ABSOLUTE(+__large_common_end - __large_common_start));
PROVIDE(__bss1_end = ABSOLUTE(.));
PROVIDE(__bss1_size = ABSOLUTE(+__bss1_end - __bss1_start));
} >EXTERNAL
/* Program arguments are loaded by `_start` routine from `__arg_sect_start`.
* When the user has set a zero size for the section, argc, and argv
* will be zero and NULL, respectively.
* Although likely small, they are on the slow path so by default they
* go at the end of external memory
*/
__ARG_SECT (NOLOAD) : ALIGN(0x4) {
__arg_sect_start = .;
. = . + (__arg_sect_size ? __arg_sect_size + 4 : 0);
__arg_sect_end = .;
} >EXTERNAL
__MALLOC_SECT (NOLOAD) : ALIGN(0x10) {
PROVIDE(__malloc_start = ABSOLUTE(.));
. = . + __malloc_size;
PROVIDE(__malloc_end = ABSOLUTE(.));
} >EXTERNAL
data_internal_loadable_addr = __data_internal_clone_start;
data_external_loadable_addr = __data_external_clone_start;
/DISCARD/ : {
/* Note: The CEVA Debugger and Restriction Checker use information
* stored in the ".note.CEVA-arch" section. Do NOT discard this section
* for projects in development phase. This section has no effect on the
* applications footprint */
*(.comment)
*(.note.GNU-stack)
/* The X-DSP ABI uses a custom relocation format stored in its own
* section. These are left in the binary by default but are unneeded. */
*(.ceva_reloc)
}
}