bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug gold/19842] LTO build fails to write call address for weak symbol r


From: matt at godbolt dot org
Subject: [Bug gold/19842] LTO build fails to write call address for weak symbol reference
Date: Sun, 20 Mar 2016 20:06:11 +0000

https://sourceware.org/bugzilla/show_bug.cgi?id=19842

--- Comment #5 from Matt Godbolt <matt at godbolt dot org> ---
Wow! What an awesome diagnosis: thank you so much for digging in to this!

I've tried with GCC 5.3.0 but not any GCC 6+ snapshots. The GCC guys on the
mailing list didn't seem to think it was a GCC bug initially but this seems
to be fairly conclusive.

I can definitely try with the 6+ snapshot but as you may imagine building
everything with the same version of GCC is a bit of an undertaking. I will
at least try building hippo with GCC6 (and hope there aren't any other ABI
differences that cause issue).

I tried hard to repro this too: the optimizer seemed to make different
decisions with a trivially small LTO program: I couldn't get it to happen.
Perhaps if you could raise this on the relevant GCC list? Of course I'd be
happy to do so too but I'd hate to get any details wrong! You've already
been more than helpful!

Thanks so much for spending your weekend on a very obscure issue!

Matt

On Sun, Mar 20, 2016 at 2:58 PM ccoutant at gmail dot com <
address@hidden> wrote:

> https://sourceware.org/bugzilla/show_bug.cgi?id=19842
>
> Cary Coutant <ccoutant at gmail dot com> changed:
>
>            What    |Removed                     |Added
>
> ----------------------------------------------------------------------------
>              Status|NEW                         |ASSIGNED
>
> --- Comment #4 from Cary Coutant <ccoutant at gmail dot com> ---
> The std::function destructor is defined as a pair of comdat symbols in
> SystemExit.o (compiled with LTO):
>
> SYMBOLS: 82 out/haswell/main/SystemExit.o
>      0: WD D _ZNSt8functionIFvvEED2Ev [comdat: _ZNSt8functionIFvvEED5Ev]
>      1: WD D _ZNSt8functionIFvvEED1Ev [comdat: _ZNSt8functionIFvvEED5Ev]
>
> and also in Server.cpp.o (not compiled with LTO):
>
>   2096: 0000000000000000    27 FUNC    WEAK   DEFAULT  846
> _ZNSt8functionIFvvEED2Ev
>   2097: 0000000000000000    27 FUNC    WEAK   DEFAULT  846
> _ZNSt8functionIFvvEED1Ev
>
> These are also declared in the _ZNSt8functionIFvvEED5Ev comdat group.
>
> (Because the D1 and D2 destructors are the same for this case, the two
> symbols
> are simply aliased to each other.)
>
> The call from std::_List_node<std::function<void ()> >::~_List_node() is
> to the
> D1 destructor:
>
> Relocation section '.rela.text._ZNSt10_List_nodeISt8functionIFvvEEED2Ev' at
> offset 0x1446b0 contains 1 entries:
>     Offset             Info             Type               Symbol's Value
> Symbol's Name + Addend
> 0000000000000018  0000083100000004 R_X86_64_PLT32         0000000000000000
> _ZNSt8functionIFvvEED1Ev - 4
>
> When processing SystemExit.o, the plugin claims it, and provides those two
> symbols to the linker. This is the first instance of a
> _ZNSt8functionIFvvEED5Ev
> comdat group, so the linker treats this as the "kept" group.
>
> When we later see Server.cpp.o, we discard its copy of that comdat group,
> and
> the reference to the destructor is expected to resolve to the earlier
> definition.
>
> When the LTO plugin is ready to generate final code, it asks the linker
> for the
> status of those two symbols, and is told (via the -lm.res file):
>
> out/haswell/main/SystemExit.o 82
> 10879 24ebb94a838bed5c PREVAILING_DEF _ZNSt8functionIFvvEED2Ev
> 10842 24ebb94a838bed5c PREVAILING_DEF _ZNSt8functionIFvvEED1Ev
>
> PREVAILING_DEF indicates that the IR contains a prevailing definition of
> the
> symbol, but that there are references to that symbol from outside the set
> of IR
> code (i.e., from Server.cpp.o). That tells the plugin that the compiler
> must
> generate a global definition of those symbols. (If there were no other
> references to the symbol, the resolution would have been
> PREVAILING_DEF_IRONLY.
> That would have allowed the compiler to generate a local definition.)
>
> But when the compiler sends back the generated file
> hippo.ltrans1.ltrans.o, it
> has defined these symbols as local:
>
>     30: 0000000000000270    33 FUNC    LOCAL  DEFAULT    1
> _ZNSt8functionIFvvEED2Ev
>     32: 0000000000000270    33 FUNC    LOCAL  DEFAULT    1
> _ZNSt8functionIFvvEED1Ev
>
> As a result, the "placeholder" symbols that the linker has kept remain
> undefined, and we end up resolving the reference from Server.cpp.o to 0.
>
> Gold should not be silently resolving this symbol to 0 -- instead, it
> should
> diagnose the compiler's failure to provide the expected definition and
> print an
> error message.
>
> I don't know how or why Gnu ld is resolving the symbol; I would expect the
> same
> behavior from it.
>
> So it looks to me (at the moment, at least) like this is a GCC bug. I'll
> try to
> come up with a simple test case, but it's often hard to reproduce the
> exact set
> of conditions that cause the optimizer to make a particular decision. It's
> possible this has been fixed since GCC 5.2 -- have you tried a newer GCC?
>
> -cary
>
> --
> You are receiving this mail because:
> You reported the bug.

-- 
You are receiving this mail because:
You are on the CC list for the bug.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]