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