From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pf1-x434.google.com (mail-pf1-x434.google.com [IPv6:2607:f8b0:4864:20::434]) by sourceware.org (Postfix) with ESMTPS id EFFAC3861970 for ; Thu, 9 Jul 2020 20:00:58 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org EFFAC3861970 Received: by mail-pf1-x434.google.com with SMTP id 207so1474398pfu.3 for ; Thu, 09 Jul 2020 13:00:58 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=fsxbQldPNd6Hu3OK2waV78QvF4e3eZPiAzhopRDffL4=; b=udkOd8eey4N1LllpMfYqQU6u0L4CUjzqKqKTss8oSz43lf0S8iM/UdLATDhLnrgGy8 9Rdj+KRbNyIvBBj9UuZXibOmR3BY9PvWzDmpDKYFo47hvGnpVjK4ibO+FP1feYxdG1V6 OuHh98Xoyek3iXGFGN+W1qq1Fc8kspJ66L2oRkrR+1vM87iUA4eLQFeF+CPjA2KUajo4 QQW0ERuVriSadKRxbEql6QFJuBN4zq5568znnm0AaujwLpj/bNiImJ5CEaFs2TWLaCtC tX99c8vXMkihPl3Dsag8MI4BrFjRu/guR5Iwh9hTdubtPe4+LEYhsYxdy7VmhmJyb47e Keag== X-Gm-Message-State: AOAM532/j9WW+YtvWYaCQmsD/tvQkJBjNy11olUzluE8HJq8FeBSl39o A3GKjR3KTTDykeOTlvfTaGyixPBR21gFNjJOszOotA== X-Google-Smtp-Source: ABdhPJygACRxWJGjWiUwdjv3wyCXDAoTD7dgqSQI7AjvI4eoMVvNOekGZQNp8S5MVs/GWrBdclOUkLBPhGbblAFl55A= X-Received: by 2002:a65:6447:: with SMTP id s7mr56141895pgv.320.1594324857780; Thu, 09 Jul 2020 13:00:57 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Alice Wang Date: Thu, 9 Jul 2020 13:00:47 -0700 Message-ID: Subject: Re: Symbol resolution differs when building with LTO compared to building without To: "Kewen.Lin" Cc: gcc-help@gcc.gnu.org X-Spam-Status: No, score=-0.8 required=5.0 tests=BAYES_00, BODY_8BITS, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, HTML_MESSAGE, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Content-Filtered-By: Mailman/MimeDel 2.1.29 X-BeenThere: gcc-help@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-help mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 09 Jul 2020 20:01:01 -0000 Hi Kewen, The ticket you linked does sound similar. And thanks for your suggestions. I tried them out and summarized the results below: 1) Don't use linker-plugin, use -fno-use-linker-plugin explicitly. The build finishes and outputs the result I expect. My custom implementation of _write is pulled into the final binary. But wouldn't -fno-use-linker-plugin effectively disable LTO in the sense that my project won't be able to take advantage of more aggressive interprocedural optimizations? 2) Use shared library instead of static library for _write library. I can't use a shared library in my case since I'm compiling for an embedded target without any sort of dynamic linker. 3) -Wl,--whole-archive -l -Wl,--no-whole-archive I changed the build command to the following: @$(CC) $(FLAGS) -fuse-linker-plugin -fno-common -Wl,-Map=3Doutput.map -Wl,--gc-sections -o $@ -Wl,--start-group main.a -lc -Wl,--end-group -Wl,--whole-archive _my_write.a -Wl,--no-whole-archive Result: *```* > LTO=3D1 make .cmake/install/GNUARM-9.2.1-Darwin/bin/../lib/gcc/arm-none-eabi/9.3.1/../..= /../../arm-none-eabi/bin/ld: /Users/aw/.cmake/install/GNUARM-9.2.1-Darwin/bin/../lib/gcc/arm-none-eabi/9= .3.1/../../../../arm-none-eabi/lib/thumb/v7e-m/nofp/libc_nano.a(lib_a-write= r.o): in function `_write_r': writer.c:(.text._write_r+0x10): undefined reference to `_write' collect2: error: ld returned 1 exit status make: *** [main.elf] Error 1 ``` Can't seem to link when using whole archives. If you have any more suggestions, it would be much appreciated! From, Aw On Sun, Jun 28, 2020 at 4:54 AM Kewen.Lin wrote: > on 2020/6/16 =E4=B8=8A=E5=8D=8810:56, Alice Wang via Gcc-help wrote: > > 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. I= n > > short, when building the project without LTO, a function will resolve t= o > 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 LT= O > > 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 LT= O > > and dumping the resulting binary shows that `_write` is my stub > > implementation. `LTO=3D1 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 =E2=9D=AF=E2=9D=AF=E2=9D=AF make > > > > Final binary: > > 00008ae0 <_write>: > > 8ae0: 4610 mov r0, r2 > > 8ae2: 4770 bx lr > > > > ~/D/lto_test =E2=9D=AF=E2=9D=AF=E2=9D=AF make clean > > ~/D/lto_test =E2=9D=AF=E2=9D=AF=E2=9D=AF LTO=3D1 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=3D1 make > > > > Repro project: > > > > main.c > > ``` > > #include > > #include > > #include > > #include > > > > int main(int argc, char *argv[]) { > > printf("Hello.\n"); > > return 0; > > } > > ``` > > > > write.c > > ``` > > #include > > > > 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 installatio= n > of > > the ARM 2020 Q2 toolchain. > > ``` > > TOOLCHAIN=3D > > LTO_PLUGIN=3D$(TOOLCHAIN)/lib/gcc/arm-none-eabi/9.3.1/liblto_plugin.so > > > > CC=3D$(TOOLCHAIN)/bin/arm-none-eabi-gcc > > AR=3D$(TOOLCHAIN)/bin/arm-none-eabi-ar > > DUMP=3D$(TOOLCHAIN)/bin/arm-none-eabi-objdump > > NM=3D$(TOOLCHAIN)/bin/arm-none-eabi-gcc-nm > > > > FLAGS=3D-g -Os -mthumb -mcpu=3Dcortex-m4 -ffunction-sections -fdata-sec= tions > > --specs=3Dnano.specs --specs=3Dnosys.specs > > ifeq ($(LTO),1) > > FLAGS+=3D-flto -ffat-lto-objects > > endif > > > > > > .PHONY: dump > > dump: main.elf _my_write.o > > @echo "\n=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D Dump =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D" > > @$(NM) -nS _my_write.o > > @echo "\n=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D F= inal binary =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D" > > @$(DUMP) -d $< | grep "<_write>:" -A 6 > > @echo "\n=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D _my_write.o =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D" > > @$(DUMP) -d $(word 2,$^) | grep "<_write>:" -A 6 > > @echo "\n=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D libnosys =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D" > > @$(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=3Doutput.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 > > > > Hi Alice, > > This symptom made me recall one PR > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D91287 > > Sorry that I don't have the environment for reproduction locally. > > Do you mind to try each of below: > 1) Don't use linker-plugin, use -fno-use-linker-plugin explicitly. > 2) Use shared library instead of static library for _write library. > 3) -Wl,--whole-archive -l > -Wl,--no-whole-archive > > HTH. > > BR, > Kewen >