Bug 15435

Summary: Gold rejects undefined weak hidden symbol
Product: binutils Reporter: Chris Smowton <chris>
Component: binutilsAssignee: Cary Coutant <ccoutant>
Status: RESOLVED FIXED    
Severity: normal CC: ppluzhnikov, rafael
Priority: P2    
Version: 2.24   
Target Milestone: ---   
See Also: https://sourceware.org/bugzilla/show_bug.cgi?id=32071
Host: Target:
Build: Last reconfirmed:
Attachments: Assembly testcase

Description Chris Smowton 2013-05-06 17:19:49 UTC
If I try to link a file that contains a weak hidden undefined symbol, Gold complains "hidden symbol 'foo' is not defined locally" (from target-reloc.h:404, where weak symbols are disregarded but /any/ symbol with non-default visibility, including weak ones, are required to be defined).

In the event this was produced by using the LLVMgold plugin, which has the interesting behaviour that when processing an LLVM declaration like

declare extern_weak hidden void @_stdio_init() (example from uclibc)

the LLVM plugin actually disguises the fact that the extern is annotated hidden and just describes it was weak-undef to Gold. However its subterfuge cannot last, and it is discovered after LLVM lowers the LTO'd IR to a plain ELF binary and Gold rereads, I guess to check if LLVM introduced calls (e.g. to memcpy). At that stage it notices the extern is still declared hidden-weak-undef and merges the symbol table entries.

One could argue this is a bug in LLVM (and I shall submit this report to their tracker as well) and that the idea of hidden-undefined doesn't make sense. I would argue a change is warranted in gold either way:

1. If you think hidden-weak-undef isn't sensible, report "illegal attributes for symbol foo" rather than "not defined here"
2. If you think it is, disregard like any other weak-undef.
Comment 1 Chris Smowton 2013-05-06 17:44:17 UTC
LLVM tracker entry: http://llvm.org/bugs/show_bug.cgi?id=15919
Comment 2 Rafael Ávila de Espíndola 2013-05-06 19:09:08 UTC
Created attachment 7016 [details]
Assembly testcase

This reproduces with
$ gcc test.s -o test.so -shared

When using gold as the linker. When the linker is the bfd ld the undefined weak hidden symbol is resolved to null.
Comment 3 Paul Pluzhnikov 2014-01-23 23:43:31 UTC
Just hit this one too, using
GNU gold (GNU Binutils 2.24.51.20131021) 1.11

The test case doesn't need any assembly:

extern void undefined () __attribute__((visibility("hidden")))
  __attribute__((weak));

int main ()
{
  if (&undefined != 0) return 1;
  return 0;
}
Comment 4 Paul Pluzhnikov 2014-01-23 23:48:48 UTC
And confirmed in current trunk:
GNU gold (GNU Binutils 2.24.51.20131021) 1.11
Comment 5 Sourceware Commits 2014-02-06 07:05:44 UTC
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "gdb and binutils".

The branch, master has been updated
       via  1a221d3d9cc474b8a382f6aeed56671d10b71473 (commit)
      from  e889f0a4b14d265cb6ef5f51bdf0daeb0d7caf1e (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=1a221d3d9cc474b8a382f6aeed56671d10b71473

commit 1a221d3d9cc474b8a382f6aeed56671d10b71473
Author: Cary Coutant <ccoutant@google.com>
Date:   Wed Feb 5 22:59:02 2014 -0800

    Fix issues with gold undefined symbol diagnostics.
    
    PR binutils/15435 complains that gold issues a visibility error for an
    weak undefined symbol with hidden visibility. The message should be
    suppressed if the symbol is a weak undef.
    
    An earlier patch to add an extra note about key functions when a class's
    vtable symbol is undefined missed a case where the reference to the
    vtable came from a shared library. This patch moves the check to a
    lower-level routine that catches both cases.
    
    gold/
    
    2014-02-05  Cary Coutant  <ccoutant@google.com>
    
    	* errors.cc (Errors::undefined_symbol): Move undef vtable symbol
    	check to here.
    	* target-reloc.h (is_strong_undefined): New function.
    	(relocate_section): Move undef vtable symbol check from here.
    	Check for is_strong_undefined.

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

Summary of changes:
 gold/ChangeLog      |   11 +++++++++++
 gold/errors.cc      |    5 +++++
 gold/target-reloc.h |   16 ++++++++--------
 3 files changed, 24 insertions(+), 8 deletions(-)
Comment 6 Cary Coutant 2014-02-06 07:14:24 UTC
Fixed on trunk.