MadVocoder42
MadVocoder42

Reputation: 93

LD Linker script EXCLUDE_FILE doesn't exclude object file from text section

I need to configure in an embedded application capability to writing to a QSPI NOR flash chip while execute in place (XIP) is enabled on an IMXRT106* chip. This requires me to have all function calls that change the state FLEXSPI peripheral to be located in RAM while configuration is taking place.

Using the NXP flexspi driver fsl_flexspi.c I need to locate that code in RAM via the linker script. Short from using __attribute__((section(".ramfunc.$RAM3))) on every function call found in fsl_flexspi.c, I can locate those calls in ram via linker script.

I modified the linker script to:

...
    .text : ALIGN(4) /*Changed this section*/
    {
     *(EXCLUDE_FILE(*fsl_flexspi.o).text* ) *(.rodata .rodata.* .constdata .constdata.*)
      /* *(.text*)*/
      /* *(.rodata .rodata.* .constdata .constdata.*)*/
       . = ALIGN(4);
    } > BOARD_FLASH

...
   .data_RAM3 : ALIGN(4)
    {
        FILL(0xff)
        PROVIDE(__start_data_RAM3 = .) ;
        PROVIDE(__start_data_SRAM_ITC = .) ;
        *(.ramfunc.$RAM3)
        *(.ramfunc.$SRAM_ITC)
        *(.data.$RAM3)
        *(.data.$SRAM_ITC)
        *(.data.$RAM3.*)
        *(.data.$SRAM_ITC.*)
        drivers/fsl_flexspi.o (.text.*) <-- I added this
        . = ALIGN(4) ;
        PROVIDE(__end_data_RAM3 = .) ;
        PROVIDE(__end_data_SRAM_ITC = .) ;
     } > SRAM_ITC AT>BOARD_FLASH

However, I get the 'multiple definition' linking error. I can't seem to nail down the correct syntax for EXCLUDE_FILE linker script line.

Linking Error Messages

  arm-none-eabi-gcc -nostdlib -Xlinker -Map="FlashWrite.map" -Xlinker -print-memory-usage -Xlinker --sort-section=alignment -Xlinker --cref -mcpu=cortex-m7 -mfpu=fpv5-sp-d16 -mfloat-abi=hard -mthumb -T FlashWrite_ldde.ld -L C:/Devel/source/FlashWrite/source -o "FlashWrite.axf"  ./xip/evkmimxrt1060_flexspi_nor_config.o ./xip/fsl_flexspi_nor_boot.o  ./startup/startup_mimxrt1062.o  ./source/FlashWrite.o ./source/Uart.o ./source/dmaMemcpy.o ./source/init.o ./source/printQue.o ./source/semihost_hardfault.o  ./drivers/fsl_clock.o ./drivers/fsl_common.o ./drivers/fsl_flexspi.o  ./device/system_MIMXRT1062.o   
Memory region         Used Size  Region Size  %age Used
     BOARD_FLASH:       80936 B      8160 KB      0.97%
     CONFIG_AREA:          24 B        32 KB      0.07%
         SRAM_OC:       10812 B       768 KB      1.37%
        SRAM_DTC:       17172 B       128 KB     13.10%
c:/nxp/mcuxpressoide_11.1.1_3241/ide/plugins/com.nxp.mcuxpresso.tools.win32_11.1.0.202001081728/tools/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld.exe: drivers/fsl_flexspi.o: in function `FLEXSPI_GetInstance':
C:\Devel\source\FlashWrite\Debug/../drivers/fsl_flexspi.c:124: multiple definition of `FLEXSPI_GetInstance'; ./drivers/fsl_flexspi.o:C:\Devel\source\FlashWrite\Debug/../drivers/fsl_flexspi.c:124: first defined here
c:/nxp/mcuxpressoide_11.1.1_3241/ide/plugins/com.nxp.mcuxpresso.tools.win32_11.1.0.202001081728/tools/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld.exe: drivers/fsl_flexspi.o: in function `FLEXSPI_CheckAndClearError':
C:\Devel\source\FlashWrite\Debug/../drivers/fsl_flexspi.c:197: multiple definition of `FLEXSPI_CheckAndClearError'; ./drivers/fsl_flexspi.o:C:\Devel\source\FlashWrite\Debug/../drivers/fsl_flexspi.c:197: first defined here
c:/nxp/mcuxpressoide_11.1.1_3241/ide/plugins/com.nxp.mcuxpresso.tools.win32_11.1.0.202001081728/tools/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld.exe: drivers/fsl_flexspi.o: in function `FLEXSPI_Init':
C:\Devel\source\FlashWrite\Debug/../drivers/fsl_flexspi.c:243: multiple definition of `FLEXSPI_Init'; ./drivers/fsl_flexspi.o:C:\Devel\source\FlashWrite\Debug/../drivers/fsl_flexspi.c:243: first defined here
c:/nxp/mcuxpressoide_11.1.1_3241/ide/plugins/com.nxp.mcuxpresso.tools.win32_11.1.0.202001081728/tools/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld.exe: drivers/fsl_flexspi.o: in function `FLEXSPI_GetDefaultConfig':
C:\Devel\source\FlashWrite\Debug/../drivers/fsl_flexspi.c:336: multiple definition of `FLEXSPI_GetDefaultConfig'; ./drivers/fsl_flexspi.o:C:\Devel\source\FlashWrite\Debug/../drivers/fsl_flexspi.c:336: first defined here
c:/nxp/mcuxpressoide_11.1.1_3241/ide/plugins/com.nxp.mcuxpresso.tools.win32_11.1.0.202001081728/tools/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld.exe: drivers/fsl_flexspi.o: in function `FLEXSPI_Deinit':
C:\Devel\source\FlashWrite\Debug/../drivers/fsl_flexspi.c:390: multiple definition of `FLEXSPI_Deinit'; ./drivers/fsl_flexspi.o:C:\Devel\source\FlashWrite\Debug/../drivers/fsl_flexspi.c:390: first defined here
c:/nxp/mcuxpressoide_11.1.1_3241/ide/plugins/com.nxp.mcuxpresso.tools.win32_11.1.0.202001081728/tools/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld.exe: drivers/fsl_flexspi.o: in function `FLEXSPI_SetFlashConfig':
C:\Devel\source\FlashWrite\Debug/../drivers/fsl_flexspi.c:407: multiple definition of `FLEXSPI_SetFlashConfig'; ./drivers/fsl_flexspi.o:C:\Devel\source\FlashWrite\Debug/../drivers/fsl_flexspi.c:407: first defined here
c:/nxp/mcuxpressoide_11.1.1_3241/ide/plugins/com.nxp.mcuxpresso.tools.win32_11.1.0.202001081728/tools/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld.exe: drivers/fsl_flexspi.o: in function `FLEXSPI_UpdateLUT':
C:\Devel\source\FlashWrite\Debug/../drivers/fsl_flexspi.c:509: multiple definition of `FLEXSPI_UpdateLUT'; ./drivers/fsl_flexspi.o:C:\Devel\source\FlashWrite\Debug/../drivers/fsl_flexspi.c:509: first defined here
c:/nxp/mcuxpressoide_11.1.1_3241/ide/plugins/com.nxp.mcuxpresso.tools.win32_11.1.0.202001081728/tools/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld.exe: drivers/fsl_flexspi.o: in function `FLEXSPI_UpdateRxSampleClock':
C:\Devel\source\FlashWrite\Debug/../drivers/fsl_flexspi.c:541: multiple definition of `FLEXSPI_UpdateRxSampleClock'; ./drivers/fsl_flexspi.o:C:\Devel\source\FlashWrite\Debug/../drivers/fsl_flexspi.c:541: first defined here
c:/nxp/mcuxpressoide_11.1.1_3241/ide/plugins/com.nxp.mcuxpresso.tools.win32_11.1.0.202001081728/tools/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld.exe: drivers/fsl_flexspi.o: in function `FLEXSPI_WriteBlocking':
C:\Devel\source\FlashWrite\Debug/../drivers/fsl_flexspi.c:570: multiple definition of `FLEXSPI_WriteBlocking'; ./drivers/fsl_flexspi.o:C:\Devel\source\FlashWrite\Debug/../drivers/fsl_flexspi.c:570: first defined here
c:/nxp/mcuxpressoide_11.1.1_3241/ide/plugins/com.nxp.mcuxpresso.tools.win32_11.1.0.202001081728/tools/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld.exe: drivers/fsl_flexspi.o: in function `FLEXSPI_ReadBlocking':
C:\Devel\source\FlashWrite\Debug/../drivers/fsl_flexspi.c:629: multiple definition of `FLEXSPI_ReadBlocking'; ./drivers/fsl_flexspi.o:C:\Devel\source\FlashWrite\Debug/../drivers/fsl_flexspi.c:629: first defined here
c:/nxp/mcuxpressoide_11.1.1_3241/ide/plugins/com.nxp.mcuxpresso.tools.win32_11.1.0.202001081728/tools/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld.exe: drivers/fsl_flexspi.o: in function `FLEXSPI_TransferBlocking':
C:\Devel\source\FlashWrite\Debug/../drivers/fsl_flexspi.c:716: multiple definition of `FLEXSPI_TransferBlocking'; ./drivers/fsl_flexspi.o:C:\Devel\source\FlashWrite\Debug/../drivers/fsl_flexspi.c:716: first defined here
c:/nxp/mcuxpressoide_11.1.1_3241/ide/plugins/com.nxp.mcuxpresso.tools.win32_11.1.0.202001081728/tools/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld.exe: drivers/fsl_flexspi.o: in function `FLEXSPI_TransferCreateHandle':
C:\Devel\source\FlashWrite\Debug/../drivers/fsl_flexspi.c:786: multiple definition of `FLEXSPI_TransferCreateHandle'; ./drivers/fsl_flexspi.o:C:\Devel\source\FlashWrite\Debug/../drivers/fsl_flexspi.c:786: first defined here
c:/nxp/mcuxpressoide_11.1.1_3241/ide/plugins/com.nxp.mcuxpresso.tools.win32_11.1.0.202001081728/tools/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld.exe: drivers/fsl_flexspi.o: in function `FLEXSPI_TransferHandleIRQ':
C:\Devel\source\FlashWrite\Debug/../drivers/fsl_flexspi.c:942: multiple definition of `FLEXSPI_TransferHandleIRQ'; ./drivers/fsl_flexspi.o:C:\Devel\source\FlashWrite\Debug/../drivers/fsl_flexspi.c:942: first defined here
c:/nxp/mcuxpressoide_11.1.1_3241/ide/plugins/com.nxp.mcuxpresso.tools.win32_11.1.0.202001081728/tools/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld.exe: drivers/fsl_flexspi.o: in function `FLEXSPI_TransferNonBlocking':
C:\Devel\source\FlashWrite\Debug/../drivers/fsl_flexspi.c:824: multiple definition of `FLEXSPI_TransferNonBlocking'; ./drivers/fsl_flexspi.o:C:\Devel\source\FlashWrite\Debug/../drivers/fsl_flexspi.c:824: first defined here
c:/nxp/mcuxpressoide_11.1.1_3241/ide/plugins/com.nxp.mcuxpresso.tools.win32_11.1.0.202001081728/tools/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld.exe: drivers/fsl_flexspi.o: in function `FLEXSPI_TransferGetCount':
C:\Devel\source\FlashWrite\Debug/../drivers/fsl_flexspi.c:901: multiple definition of `FLEXSPI_TransferGetCount'; ./drivers/fsl_flexspi.o:C:\Devel\source\FlashWrite\Debug/../drivers/fsl_flexspi.c:901: first defined here
c:/nxp/mcuxpressoide_11.1.1_3241/ide/plugins/com.nxp.mcuxpresso.tools.win32_11.1.0.202001081728/tools/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld.exe: drivers/fsl_flexspi.o: in function `FLEXSPI_TransferAbort':
C:\Devel\source\FlashWrite\Debug/../drivers/fsl_flexspi.c:928: multiple definition of `FLEXSPI_TransferAbort'; ./drivers/fsl_flexspi.o:C:\Devel\source\FlashWrite\Debug/../drivers/fsl_flexspi.c:928: first defined here
c:/nxp/mcuxpressoide_11.1.1_3241/ide/plugins/com.nxp.mcuxpresso.tools.win32_11.1.0.202001081728/tools/bin/../lib/gcc/arm-none-eabi/8.3.1/../../../../arm-none-eabi/bin/ld.exe: drivers/fsl_flexspi.o: in function `FLEXSPI_DriverIRQHandler':
C:\Devel\source\FlashWrite\Debug/../drivers/fsl_flexspi.c:1053: multiple definition of `FLEXSPI_DriverIRQHandler'; ./drivers/fsl_flexspi.o:C:\Devel\source\FlashWrite\Debug/../drivers/fsl_flexspi.c:1053: first defined here
collect2.exe: error: ld returned 1 exit status
        SRAM_ITC:        4688 B       128 KB      3.58%
make: *** [makefile:36: FlashWrite.axf] Error 1

At the end you can see that there is code being allocated in the SRAM_ITC but then also elsewhere. I am out of ideas, I don't know what is going on. Thanks.

Upvotes: 4

Views: 5157

Answers (1)

MadVocoder42
MadVocoder42

Reputation: 93

I still don't understand why my fix worked but since there were no actionable or educational answers to my question, I will post my solution. Its up to the Google user to sus out the 'why', but here is my how in my context:

Answer: Text section here is defined. The LD documentation to me doesn't make sense to me on how EXCLUDE_FILE works and the use below to me looks as if its not including the other ".text" objects in the ".text section".

.text : ALIGN(4)
{
 *(EXCLUDE_FILE(*fsl_flexspi.o).text.*  ) *(.rodata .rodata.* .constdata .constdata.*)
   . = ALIGN(4);
} > BOARD_FLASH

The source of my errors above are because the linker is including the translated objects in 2 sections. In my question the output shown by the linker shows that code is being included in the SRAM_ITC.

Apparently and I don't understand why, but in the .data_RAM3 section definition the correct way, in my case is below:

    .data_RAM3 : ALIGN(4)
{
    FILL(0xff)
    PROVIDE(__start_data_RAM3 = .) ;
    PROVIDE(__start_data_SRAM_ITC = .) ;
    *(.ramfunc.$RAM3)
    *(.ramfunc.$SRAM_ITC)
    *(.data.$RAM3)
    *(.data.$SRAM_ITC)
    *(.data.$RAM3.*)
    *(.data.$SRAM_ITC.*)
    *fsl_flexspi.o (.text*)
    . = ALIGN(4) ;
    PROVIDE(__end_data_RAM3 = .) ;
    PROVIDE(__end_data_SRAM_ITC = .) ;
 } > SRAM_ITC AT>BOARD_FLASH

If the reader has Googled 'EXCLUDE_FILE' a number of "answers" will show up and hopefully this one too to muddy the waters. Some linker scripts included the path of the object file in its definition. In my case, case including the relative path was causing the LD process executed by GCC some level of grief.

The manufacturer example I was following made the necessary changes in the linker script by blanket executing all code in RAM and used XML files to describe the changes of the linker script. The IDE would then process the XML file and auto generate the linker script at build time...Not very helpful.

When it comes to writing and executing (read) from the same flash chip at the same time is generally is not possible, unless explicitly called out in the flash datasheet. This is called "Read While Write" (RWW). I'm using a NOR QSPI Flash which doesn't support it. This means the code that setup and write to the flash chip has to be located in RAM.

If its a single function then using __attribute__((section(".ramfunc.$RAM3))) would work. However, if using third-party driver code and w/o modifying the source after verified to work, using the linker script to locate the entire module is "easier", without having to modify the driver source code.

To verify the expected .text objects are where they are supposed to be, look at the objdump of the binary or the linker map file.

Upvotes: 2

Related Questions