public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Symbol resolution differs when building with LTO compared to building without
@ 2020-06-16  2:56 Alice Wang
  2020-06-28 11:54 ` Kewen.Lin
  0 siblings, 1 reply; 4+ messages in thread
From: Alice Wang @ 2020-06-16  2:56 UTC (permalink / raw)
  To: gcc-help

Hi,

I've come across some unexpected behavior and I'd appreciate your input on
the issue. I have an example project below that reproduces the issue. In
short, when building the project without LTO, a function will resolve to my
expected version, but when building with LTO, the symbol is resolved to a
different definition that I do not want.

Specifically, when building without LTO (which results in the behavior I
want), the final binary will pull in the definition of `_write` from my
custom static library that is listed first in the library list. With LTO
enabled (the bad case), the final binary will pull in the definition of
`_write` from libnosys, which comes later in the list of static libraries.

The output of my test project is pasted below. `make` builds without LTO
and dumping the resulting binary shows that `_write` is my stub
implementation. `LTO=1 make` builds with LTO enabled, and dumping the
resulting binary shows the implementation comes from libnosys.

How can I enable LTO in my build while providing custom definitions for
library calls (like _write)?

~/D/lto_test ❯❯❯ make

Final binary:
00008ae0 <_write>:
    8ae0: 4610       mov r0, r2
    8ae2: 4770       bx lr

~/D/lto_test ❯❯❯ make clean
~/D/lto_test ❯❯❯ LTO=1 make

Final binary:
00008b50 <_write>:
    8b50: 4b02       ldr r3, [pc, #8] ; (8b5c <_write+0xc>)
    8b52: 2258       movs r2, #88 ; 0x58
    8b54: 601a       str r2, [r3, #0]
    8b56: f04f 30ff mov.w r0, #4294967295 ; 0xffffffff
    8b5a: 4770       bx lr
    8b5c: 00018c84 .word 0x00018c84

------------------------------------------------

Toolchain version:
ARM 9-2020-q2-update (based on the 9 series)

Repro steps:
make
make clean
LTO=1 make

Repro project:

main.c
```
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[]) {
    printf("Hello.\n");
    return 0;
}
```

write.c
```
#include  <unistd.h>

ssize_t  _write (int      fd,
                 void    *p_buf,
                 size_t   cnt)
{
    return cnt;
}
```

Makefile
Note: You'll have to change the path to point to your local installation of
the ARM 2020 Q2 toolchain.
```
TOOLCHAIN=<YOUR_PATH_TO_TOOLCHAIN>
LTO_PLUGIN=$(TOOLCHAIN)/lib/gcc/arm-none-eabi/9.3.1/liblto_plugin.so

CC=$(TOOLCHAIN)/bin/arm-none-eabi-gcc
AR=$(TOOLCHAIN)/bin/arm-none-eabi-ar
DUMP=$(TOOLCHAIN)/bin/arm-none-eabi-objdump
NM=$(TOOLCHAIN)/bin/arm-none-eabi-gcc-nm

FLAGS=-g -Os -mthumb -mcpu=cortex-m4 -ffunction-sections -fdata-sections
--specs=nano.specs --specs=nosys.specs
ifeq ($(LTO),1)
FLAGS+=-flto -ffat-lto-objects
endif


.PHONY: dump
dump: main.elf _my_write.o
@echo "\n======================== Dump ========================"
@$(NM) -nS _my_write.o
@echo "\n==================== Final binary ===================="
@$(DUMP) -d $< | grep "<_write>:" -A 6
@echo "\n====================== _my_write.o ======================"
@$(DUMP) -d $(word 2,$^) | grep "<_write>:" -A 6
@echo "\n======================= libnosys ========================"
@$(DUMP) -d $(TOOLCHAIN)/arm-none-eabi/lib/thumb/v7e-m/nofp/libnosys.a |
grep "<_write>:" -A 6

main.elf: main.a _my_write.a
@$(CC) $(FLAGS)  -fuse-linker-plugin -fno-common -Wl,-Map=output.map
-Wl,--gc-sections -o $@ -Wl,--start-group $^ -lc -Wl,--end-group

%.a: %.o
@$(AR) --plugin $(LTO_PLUGIN) -rcs $@ $<

_my_write.o: ./write.c Makefile
@$(CC) $(FLAGS) -c $< -o $@

main.o: main.c Makefile
@$(CC) $(FLAGS) -c $< -o $@

.PHONY: clean
clean:
@rm -rf _write.a main.a main.elf *.res *.out *.o *.s *.map *.dump *.a
```

Once again, any insight would be greatly appreciated. My goal is to enable
LTO in my project while being able to provide custom definitions of
specific standard library calls.

Thanks in advance.

From,
AW

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2020-07-14 10:43 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-16  2:56 Symbol resolution differs when building with LTO compared to building without Alice Wang
2020-06-28 11:54 ` Kewen.Lin
2020-07-09 20:00   ` Alice Wang
2020-07-14 10:43     ` Kewen.Lin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).