Search code examples
linkeriar

IAR Linker Configuration File - Missing ".intvec" Placement


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

Solution

  • 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.