This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Linker symbol resolution differences with LTO.


I suspect this is because you compiled 2.c without LTO. When the LTO
plugin invokes the compiler to generate code for 1.c, it sees that
there is already a definition for foo, so it doesn't bother to
generate another definition. If you compile both 1.c and 2.c with LTO,
I think it will give you the result you expect.

I think the compiler is within its rights in doing this, but I could
be wrong. (For C++, with the ODR, I'm pretty sure; for C, I'm not so
sure.)

-cary


On Mon, Dec 7, 2015 at 6:09 PM, Shankar Easwaran <shankarke@gmail.com> wrote:
> Thanks for the quick reply, Cary.
>
> I was only trying to reduce the testcase where I am seeing odd behavior with
> LTO.
>
> I am changing the testcase a bit, but still get different symbol resolution
> behavior with LTO and non LTO builds.
>
> cat > 1.c << \!
> #include <stdio.h>
>
> int bar() {
>   return 0;
> }
>
> __attribute__((weak)) int foo() {
>   printf("good\n");
>   return 0;
> }
> !
>
> cat > 2.c << \!
> #include <stdio.h>
> int main() {
>   return foo() + bar();
> }
>
> __attribute__((weak)) int foo() {
>   printf("bad\n");
>   return 1;
> }
> !
>
>
> gcc -c 1.c  -ffunction-sections -flto
> gcc -c 2.c -ffunction-sections
> gcc -flto 1.o 2.o -Wl,-y,foo -o 1
> # with LTO, prints bad
> ./1
> gcc 1.c 2.c -o 2 -Wl,-y,foo
> # without LTO, prints good
> ./2
>
> I am expecting the test to produce good in both cases.
>
> Shankar Easwaran
>
>
> On Mon, Dec 7, 2015 at 7:20 PM, Cary Coutant <ccoutant@gmail.com> wrote:
>>
>> > gcc -c 1.c  -ffunction-sections -flto
>> > gcc -c 2.c -ffunction-sections
>> > # Linker picks the definition of foo from 2.o
>> > ld 1.o 2.o -y foo
>> > 2.o: definition of foo
>>
>> If you run "nm" on 1.o, I think you'll find that there are no symbols
>> defined other than a couple of __gnu_lto_ symbols. This indicates that
>> you're compiling to "slim" objects, which contain *only* intermediate
>> code. Without the LTO plugin, the linker will find nothing to link in
>> 1.o. If you want the ability to link LTO-compiled objects without
>> using the LTO plugin, you'll want to use the -ffat-lto-objects option
>> the object file will contain not only the intermediate code (for use
>> with the linker plugin), but also regular object code that can be
>> linked without a plugin. In that case, linking with plain ld, without
>> the plugin, will pick the right definition of foo, but you will not
>> get any link-time optimization -- you'll get the same output you would
>> have gotten without any -flto options at all.
>>
>> You're not really using LTO (*Link-time* optimization) unless you use
>> "gcc -flto" for the link step as well. The gcc driver will pass the
>> necessary options to the linker to have it call the LTO plugin, which
>> will re-invoke the compiler to translate the intermediate code into
>> final object code at link time. Furthermore, if you only compile one
>> file with -flto, you won't really be gaining much at all, since the
>> link-time optimization will not be able to perform any cross-module
>> optimization.
>>
>> -cary
>
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]