gccarmstm32linker-scripts

How can I specifically exclude a libgcc function from being placed in flash memory?


I want to place a certain section of libgcc in RAM instead of in Flash of my STM32L053R8T6 microcontroller. Even while explicitly excluding a specific function in the specific object file in my linker script, it keeps reappearing in my .map file. Specifically, I want to exclude the function __gnu_thumb1_case_sqi from the flash section of the memory map of my microcontroller.

A branch to the portion of code in flash

To examine the details of the exact function being linked, I did an obj dump of the libgcc.a archive using this command

arm-none-eabi-objdump -S /usr/lib/gcc/arm-none-eabi/12.2.1/thumb/v6-m/nofp/libgcc.a | tee dump.txt

which gives the following output for the relevant function:

_thumb1_case_uqi.o:     file format elf32-littlearm


Disassembly of section .text:

00000000 <__gnu_thumb1_case_uqi>:
   0:   b402        push    {r1}
   2:   4671        mov r1, lr
   4:   0849        lsrs    r1, r1, #1
   6:   0049        lsls    r1, r1, #1
   8:   5c09        ldrb    r1, [r1, r0]
   a:   0049        lsls    r1, r1, #1
   c:   448e        add lr, r1
   e:   bc02        pop {r1}
  10:   4770        bx  lr
  12:   46c0        nop         @ (mov r8, r8)

To make sure I make the linker script exclude this exact portion of my library, I use the EXCLUDE_FILE command in the SECTIONS definition of my output file:

MEMORY
{
  RAM    (xrw)    : ORIGIN = 0x20000000,   LENGTH = 8K
  FLASH    (rx)    : ORIGIN = 0x8000000,   LENGTH = 64K
}

/* Sections */
SECTIONS
{
  /* The startup code into "FLASH" Rom type memory */
  .isr_vector :
  {
    . = ALIGN(4);
    KEEP(*(.isr_vector)) /* Startup code */
    . = ALIGN(4);
  } >FLASH

  /* The program code and other data into "FLASH" Rom type memory */
  .text :
  {
    . = ALIGN(4);

    *(EXCLUDE_FILE (libgcc.a:_thumb1_case_uqi.o) .text)           /* .text sections (code) */

    /* Exclude file(s) from libgcc.a from .text.* section   */
    *(EXCLUDE_FILE (libgcc.a:_thumb1_case_uqi.o) .text*)

    /* *(.text*) */          /* .text* sections (code) */
    *(.glue_7)         /* glue arm to thumb code */
    *(.glue_7t)        /* glue thumb to arm code */
    *(.eh_frame)

However, when I examine the .map file generated by the linker, it still places this function in the wrong region. Here is the relevant output:

                0x20002000                        _estack = (ORIGIN (RAM) + LENGTH (RAM))
                0x00000200                        _Min_Heap_Size = 0x200
                0x00000300                        _Min_Stack_Size = 0x300

.isr_vector     0x08000000       0xc0
                0x08000000                        . = ALIGN (0x4)
 *(.isr_vector)
 .isr_vector    0x08000000       0xc0 CMakeFiles/MYPROJECT.dir/Platform/MYPROJECT/GCC/startup_stm32l053xx.s.obj
                0x08000000                g_pfnVectors
                0x080000c0                        . = ALIGN (0x4)

.text           0x080000c0     0x76b8
                0x080000c0                        . = ALIGN (0x4)
 *(EXCLUDE_FILE(libgcc.a:_thumb1_case_uqi.o) .text)
 .text          0x080000c0       0x98 /usr/lib/gcc/arm-none-eabi/12.2.1/thumb/v6-m/nofp/crtbegin.o
 .text          0x08000158       0x14 /usr/lib/gcc/arm-none-eabi/12.2.1/thumb/v6-m/nofp/libgcc.a(_thumb1_case_sqi.o)
                0x08000158                __gnu_thumb1_case_sqi
 .text          0x0800016c       0x14 /usr/lib/gcc/arm-none-eabi/12.2.1/thumb/v6-m/nofp/libgcc.a(_thumb1_case_uqi.o)
                0x0800016c                __gnu_thumb1_case_uqi

How come it places this in the .text region when in the linker file I explicitly made it not place anything from the related object file?


Solution

  • As artless-noise points out, the issue was mainly about the formatting in the linker script. The main point that I overlooked was that the linker script needs the whole path of the library when using the EXCLUDE_FILE file command and not just the name of the library.

    The line I needed to use was:

        *(EXCLUDE_FILE(*libgcc.a:_thumb1_case_uqi.o *libgcc.a:_thumb1_case_sqi.o) .text)
    

    Note: I included both sqi and uqi switch cases because both can be compiled.

    The RAM section in my .map file:

     .RamFunc       0x2000027c       0xcc CMakeFiles/ThincHV_ST573NPFF.dir/Platform/ThincHV/stm32l0xx_it.c.obj
                    0x2000027c                SysTick_Handler
                    0x20000290                ADC1_COMP_IRQHandler
                    0x2000029a                TIM2_IRQHandler
                    0x200002ee                TIM21_IRQHandler
                    0x20000324                TIM22_IRQHandler
                    0x20000326                EXTI4_15_IRQHandler
                    0x20000344                TIM6_DAC_IRQHandler
     .RamFunc       0x20000348      0x304 CMakeFiles/ThincHV_ST573NPFF.dir/Components/Application/Heating/TriacQ2Q3.c.obj
                    0x2000035c                TriacQ2Q3_PostEvent
     .RamFunc       0x2000064c       0x38 CMakeFiles/ThincHV_ST573NPFF.dir/Components/Drivers/STM32_TouchSensing_Library/src/tsl_time.c.obj
                    0x2000064c                TSL_tim_ProcessIT
     .RamFunc       0x20000684       0x68 CMakeFiles/ThincHV_ST573NPFF.dir/Components/Peripherals/CRCManagement.c.obj
                    0x20000684                CRCManagement_CalculateCrc
     .RamFunc       0x200006ec       0xd4 CMakeFiles/ThincHV_ST573NPFF.dir/Components/Peripherals/EEPROMManagement.c.obj
     .RamFunc       0x200007c0       0x14 CMakeFiles/ThincHV_ST573NPFF.dir/Components/Peripherals/SystemClocks.c.obj
                    0x200007c0                HAL_IncTick
     *libgcc.a:_thumb1_case_uqi.o(.text)
     .text          0x200007d4       0x14 /usr/lib/gcc/arm-none-eabi/12.2.1/thumb/v6-m/nofp/libgcc.a(_thumb1_case_uqi.o)
                    0x200007d4                __gnu_thumb1_case_uqi
     *libgcc.a:_thumb1_case_sqi.o(.text)
     .text          0x200007e8       0x14 /usr/lib/gcc/arm-none-eabi/12.2.1/thumb/v6-m/nofp/libgcc.a(_thumb1_case_sqi.o)
                    0x200007e8                __gnu_thumb1_case_sqi
     *(.RamFunc*)
                    0x200007fc                        . = ALIGN (0x4)
                    0x200007fc                        _edata = .