https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91299

            Bug ID: 91299
           Summary: LTO inlines a weak definition in presence of a
                    non-weak definition from an ELF file
           Product: gcc
           Version: 8.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: lto
          Assignee: unassigned at gcc dot gnu.org
          Reporter: peter.smith at linaro dot org
                CC: marxin at gcc dot gnu.org
  Target Milestone: ---

The following example has been cut down from an embedded program that uses
absolute symbols to denote entry points. I've used arm-none-eabi-gcc 8.2.1 in
this example but it will reproduce on at least gcc 7.4.0 x86_64 with binutils
2.26.1 :

cat nonweakdef.s
        .globl foo
 .equ         foo, 0x10000000

cat weakdef.c
__attribute__((weak)) void foo() {}

int main(void) {
    foo();
    return 0;
}

arm-none-eabi-gcc -O3 nonweakdef.s weakdef.c -mcpu=cortex-m3 -o foo.axf
--specs=nosys.specs

produces the disassembly output for main:
 00008030 <main>:
    8030:       b508            push    {r3, lr}
    8032:       f000 e9ae       blx     8390 <__foo_veneer>
    8036:       2000            movs    r0, #0
    8038:       bd08            pop     {r3, pc}
    803a:       bf00            nop
This shows a function call to a __foo_veneer as I would expect as the
definition of foo is far away from main.

With LTO the weak definition of foo is inlined into main

arm-none-eabi-gcc -O3 nonweakdef.s weakdef.c -flto -mcpu=cortex-m3 -o foo.axf
--specs=nosys.specs

0000802c <main>:
    802c:       2000            movs    r0, #0
    802e:       4770            bx      lr

This ignores the non-weak definition in the ELF file which should take
precedence. In the embedded example this was fatal as the non-weak definition
represented the entry point for a device specific flash programming routine
overriding a platforms generic one.

I think that either the linker ld.bfd 2.31.51.20181213 is not passing the
non-weak definition information to the LTO plugin which should inhibit the
inlining of the weak definition or some optimization is enabled for LTO that
isn't accounting for a non-weak definition to be present from a non LTO source.
As such this might be a bug in binutils rather than GCC.

Reply via email to