I'm working with an IAR project where there are ILINK Configuration Files (.icf
) for both a bootloader and the main application. Each file defines the __ICFEDIT_intvec_start__
symbol and later places it referencing their respective .intvec
sections (there are 2 cstartup.s
files, each with their own .intvec
section):
Bootloader .icf
:
define symbol __ICFEDIT_intvec_start__ = 0x18000000;
...
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
Application .icf
:
define symbol __ICFEDIT_intvec_start__ = 0x18080000;
...
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
From what I understand, each of these .icf
files are used to generate their own .map
files. Seeing as how each of these reference two different sections (that share the same name), I'm confused as to why only the .map
file for the bootloader references the .intvec
section:
Bootloader .map
:
*******************************************************************************
*** PLACEMENT SUMMARY
***
"A1": place at 0x18000000 { ro section .intvec };
"P1": place in [from 0x18000040 to 0x1807ffff] { ro };
"P2": place in [from 0x20020000 to 0x209fffff] {
rw, block CSTACK, block SVC_STACK, block IRQ_STACK, block FIQ_STACK,
block UND_STACK, block ABT_STACK, block HEAP };
Section Kind Address Size Object
------- ---- ------- ---- ------
"A1": 0x3c
.intvec ro code 0x18000000 0x3c cstartup.o [1]
- 0x1800003c 0x3c
...
Application .map
:
*******************************************************************************
*** PLACEMENT SUMMARY
***
"INT_VEC_RAM":
place at 0x20020000 { section .intvec_RAM };
"ROM": place in [from 0x18080040 to 0x1bffffff] {
ro section .cstartup, block ROM_CONTENT };
"RAM": place in [from 0x20020040 to 0x209fffff] { block RAM_CONTENT };
Section Kind Address Size Object
------- ---- ------- ---- ------
"ROM": 0x2405e0
ROM_CONTENT 0x18080040 0x2405e0 <Block>
.text ro code 0x18080040 0x104 access.o [8]
.text ro code 0x18080144 0x18c cstartup.o [1]
What's happening here? I'm just starting to understand the role of the linker, so I'm fairly new to all of this.
Also, to further clarify, the two .intvec
sections comprise the same interrupt vector table:
SECTION .intvec:CODE:NOROOT(2)
...
__vector: ; Make this a DATA label, so that stack usage
; analysis doesn't consider it an uncalled fun
ARM
; All default exception handlers (except reset) are
; defined as weak symbol definitions.
; If a handler is defined by the application it will take precedence.
LDR PC,Reset_Addr ; Reset
LDR PC,Undefined_Addr ; Undefined instructions
LDR PC,SWI_Addr ; Software interrupt (SWI/SVC)
LDR PC,Prefetch_Addr ; Prefetch abort
LDR PC,Abort_Addr ; Data abort
DCD 0 ; RESERVED
LDR PC,IRQ_Addr ; IRQ
LDR PC,FIQ_Addr ; FIQ
It seems that the answer is a lot more obvious than I thought. According to the section "Linking—an overview" in "IAR C/C++ Development Guide", IAR's linker software ILINK ignores duplicate sections. Thus, if a section is already referenced in one binary object or ILINK configuration file (ICF), all other references to it are ignored.
In this project, since the bootloader takes precedence (is loaded and flashed before the application [defined in the project's .board
files; more info here]), the application code's .intvec
is seen as a duplicate and is thus ignored/discarded.