GNU LD "EXCLUDE_FILE" keyword doesn't work at all, while using gcc "-flto" option

Asked by PANDA

Hi All,

 Here is all the files I am using:

  "main.c":
    void b(void);
    void c(void);
    void a(void);
    void CM3_Handler(void)
    {
        /* dead loop here */
        for (;;)
        {}
    }
    void Reset_Handler(void)
    {
        a();
        b();
        c();
    }
    __attribute__((__section__(".isr_vector")))
    __attribute__((__used__))
    void (*IsrVectorTable[16])(void) =
    {
        /* cortex-m3 standard system exception */
        (void *)0x20008000, /* stack bottom */
        Reset_Handler, /* reset */
        CM3_Handler, /* NMI */
        CM3_Handler, /* hard fault */
        CM3_Handler, /* memory management fault */
        CM3_Handler, /* bus fault */
        CM3_Handler, /* usage fault */
        CM3_Handler, /* reserved */
        CM3_Handler, /* reserved */
        CM3_Handler, /* reserved */
        CM3_Handler, /* reserved */
        CM3_Handler, /* SVC */
        CM3_Handler, /* debug monitor */
        CM3_Handler, /* reserved */
        CM3_Handler, /* PendSV */
        CM3_Handler, /* SysTick */
    };

 "test.c":
    __attribute__ (( noinline )) void b(void)
    {
        volatile int v;

        v = *(volatile int *)0x1000;
        if (v)
        {}
    }
    __attribute__ (( noinline )) void c(void)
    {
        volatile int v;

        v = *(volatile int *)0x1200;
        if (v)
        {}
    }
    __attribute__ (( noinline )) void a(void)
    {
        volatile int v;

        v = *(volatile int *)0x1100;
        if (v)
        {}
    }

 "Makefile":
    CC = arm-none-eabi-gcc
    NM = arm-none-eabi-nm
    C_FLAGS = -mcpu=cortex-m3 -mthumb -mlittle-endian
    LD_FLAGS = -nostartfiles -T mcu.ld
    .PHONY: all
    all:
     $(CC) -c $(C_FLAGS) -I. main.c -o main.o
     $(CC) -c $(C_FLAGS) -I. test.c -o test.o
     $(CC) $(LD_FLAGS) main.o test.o -Wl,--output=main.elf
     $(NM) -n -S main.elf > main.sym

 "mcu.ld":
    ENTRY(IsrVectorTable)

    /* memory definition */
    MEMORY
    {
        rom0(rx) : ORIGIN = 0x00000000, LENGTH = 100K
        rom1(rx) : ORIGIN = 0x00020000, LENGTH = 100K
        ram (rw) : ORIGIN = 0x20000000, LENGTH = 32K
    }

    /* section definition */
    SECTIONS
    {
        .section1 : ALIGN(4)
        {
            test.o(.text*)
        } >rom0

        .section2 : ALIGN(4)
        {
            KEEP (*(.isr_vector))
            main.o(.text*)
            *(.rodata*)
        } >rom1

        . = ALIGN(4);
        __text_end = .;

        .data : ALIGN(4)
        {
            *(.data*)
        } >ram AT>rom1

        . = ALIGN(4);
        __data_end = .;

        .bss : ALIGN(4)
        {
            *(.bss*)
        } >ram

        . = ALIGN(4);
        __bss_end = .;
    }

 In the "mcu.ld" file, what I am trying to do, is to separate all ".text" section in test.c into "rom0" memory, and all other sections (including ".text" section in main.c) into "rom1" memory. But, when I add the "-flto" option in the C_FLAGS of "Makefile", after compiled, I found that the generated "main.sym" content is shown as below:
    00000000 00000006 t CM3_Handler
    00000008 00000012 t Reset_Handler
    0000001c 0000001a t b
    00000038 0000001a t c
    00000054 0000001a t a
    00020000 00000040 D IsrVectorTable
    00020040 D __bss_end
    00020040 D __data_end
    00020040 D __text_end
 We can see that, all ".text" section in main.c are still in "rom0", not "rom1" as I expected.
 But, when I remove the "-flto" option, and re-compile, the "main.sym" content is shown as below:
    00000000 0000001a T b
    0000001c 0000001a T c
    00000038 0000001a T a
    00020000 00000040 T IsrVectorTable
    00020040 00000006 T CM3_Handler
    00020048 00000012 T Reset_Handler
    0002005c T __bss_end
    0002005c T __data_end
    0002005c T __text_end
 This is exactly what I want.

 So, here comes the question, what can I do to work-around this issue, with GNU ld "EXCLUDE_FILE" keyword and gcc "-flto" option both used?

 BTW, I am using the official released "gcc-arm-none-eabi-4_9-2015q3-20150921-win32.zip" as compiler running under 64-bit Windows10.
 Any missing or unclear parts, please just contact me at: yaxi1984#gmail.com (please change # to @)

Question information

Language:
English Edit question
Status:
Solved
For:
GNU Arm Embedded Toolchain Edit question
Assignee:
No assignee Edit question
Solved by:
Joey Ye
Solved:
Last query:
Last reply:
Revision history for this message
Best Joey Ye (jinyun-ye) said :
#1

The way GCC lto works is like treating the whole program as a single compilation unit, thus results in conceptually a single .o. I think it is why ld cannot choose based on object file name.

To work around it, I would recommend __attribute__((section(".rom0")) to all functions in test.c. Then use section names rather than objctive names in linker script.

Hope it works for you.

Revision history for this message
PANDA (yaxi1984) said :
#2

Thanks Joey Ye, that solved my question.