Bug 230399

Summary: devel/libunwind: fails to build with Clang 7
Product: Ports & Packages Reporter: Jan Beich <jbeich>
Component: Individual Port(s)Assignee: freebsd-toolchain (Nobody) <toolchain>
Status: Closed FIXED    
Severity: Affects Only Me CC: danilo, dim, emaste, koobs, linimon
Priority: --- Keywords: needs-qa, toolchain
Version: LatestFlags: koobs: merge-quarterly?
Hardware: Any   
OS: Any   
See Also: https://bugs.llvm.org/show_bug.cgi?id=38506
Bug Depends on:    
Bug Blocks: 230355    
Attachments:
Description Flags
workaround none

Description Jan Beich freebsd_committer freebsd_triage 2018-08-06 00:12:13 UTC
$ cc -v
FreeBSD clang version 7.0.0 (branches/release_70 338892) (based on LLVM 7.0.0svn)
Target: x86_64-unknown-freebsd12.0
Thread model: posix
InstalledDir: /usr/bin

$ make
[...]
Making all in tests
/bin/sh ../libtool  --tag=CC    --mode=link cc  -O2 -pipe -O3 -fno-omit-frame-pointer -march=native  -fstack-protector -fexceptions -Wall -Wsign-compare   -fstack-protector -fuse-ld=bfd -o Gperf-simple Gperf-simple.o ../src/libunwind-x86_64.la ../src/libunwind.la
libtool: link: cc -O2 -pipe -O3 -fno-omit-frame-pointer -march=native -fstack-protector -fexceptions -Wall -Wsign-compare -fstack-protector -fuse-ld=bfd -o .libs/Gperf-simple Gperf-simple.o  ../src/.libs/libunwind-x86_64.so /tmp/a/overlay/ports/devel/libunwind/work/libunwind-1.2.1/src/.libs/libunwind.so ../src/.libs/libunwind.so -lgcc_s -llzma -Wl,-rpath -Wl,/usr/local/lib
/usr/lib/libgcc_s.so: undefined reference to `__gxx_personality_v0'
cc: error: linker command failed with exit code 1 (use -v to see invocation)
*** Error code 1

build log: https://ptpb.pw/pyiT
Comment 1 Jan Beich freebsd_committer freebsd_triage 2018-08-06 00:14:25 UTC
Ignore custom CFLAGS (e.g., -O3 -march=native) in comment 0, they're not present in the build log.
Comment 2 Jan Beich freebsd_committer freebsd_triage 2018-08-06 13:34:18 UTC
Probably affects a number of LLD_UNSAFE ports:

$ echo 'int main() {}' >a.c
$ cc a.c -lexecinfo
$ cc a.c -fuse-ld=bfd -lexecinfo
/usr/lib/libgcc_s.so: undefined reference to `__gxx_personality_v0'
cc: error: linker command failed with exit code 1 (use -v to see invocation)
Comment 3 Jan Beich freebsd_committer freebsd_triage 2018-08-06 16:22:38 UTC
__gcc_personality_v0 is implemented by compiler-rt, while __gxx_personality_v0 is implemented by libcxxrt. LLD appears to use its own dependency on libc++ to resolve missing symbols. Even Gold (another C++ linker) doesn't allow this.
Comment 4 Jan Beich freebsd_committer freebsd_triage 2018-08-06 16:32:30 UTC
Created attachment 195944 [details]
workaround
Comment 5 Dimitry Andric freebsd_committer freebsd_triage 2018-08-09 19:47:34 UTC
(In reply to Jan Beich from comment #2)
> Probably affects a number of LLD_UNSAFE ports:
> 
> $ echo 'int main() {}' >a.c
> $ cc a.c -lexecinfo
> $ cc a.c -fuse-ld=bfd -lexecinfo
> /usr/lib/libgcc_s.so: undefined reference to `__gxx_personality_v0'
> cc: error: linker command failed with exit code 1 (use -v to see invocation)

It's weird, the __gxx_personality_v0 symbol is referenced from libunwind.pico, built during the libgcc_s build.

libunwind.pico is built from contrib/llvm/projects/libunwind/src/libunwind.cpp, which indeed is a C++ source file, so somehow this C++ specific symbol gets in, but it did not in the previous version of clang.

Investigating...
Comment 6 Dimitry Andric freebsd_committer freebsd_triage 2018-08-09 19:54:11 UTC
This is how libunwind.s built with clang 6.0.1 ends:

        .ident  "FreeBSD clang version 6.0.1 (tags/RELEASE_601/final 335540) (based on LLVM 6.0.1)"
        .section        ".note.GNU-stack","",@progbits
        .section        .debug_line,"",@progbits
.Lline_table_start0:

Compare to this with clang 7.0.0:

        .ident  "FreeBSD clang version 7.0.0 (branches/release_70 338892) (based on LLVM 7.0.0svn)"
        .section        ".note.GNU-stack","",@progbits
        .addrsig
        .addrsig_sym __gxx_personality_v0
        .addrsig_sym _ZZN9libunwind17LocalAddressSpace18findUnwindSectionsEmRNS_18UnwindInfoSectionsEENUlP12dl_phdr_infomPvE_8__invokeES4_mS5_
        .addrsig_sym _ZN9libunwind17LocalAddressSpace17sThisAddressSpaceE
        .addrsig_sym _ZN9libunwind13DwarfFDECacheINS_17LocalAddressSpaceEE5_lockE
        .addrsig_sym _ZN9libunwind13DwarfFDECacheINS_17LocalAddressSpaceEE14_initialBufferE
        .section        .debug_line,"",@progbits
.Lline_table_start0:

For some reason, it adds these .addrsig_sym directives, but no idea what they're for.
Comment 7 Dimitry Andric freebsd_committer freebsd_triage 2018-08-09 20:42:13 UTC
Reported upstream: https://bugs.llvm.org/show_bug.cgi?id=38506
Comment 8 commit-hook freebsd_committer freebsd_triage 2018-08-10 19:58:35 UTC
A commit references this bug:

Author: dim
Date: Fri Aug 10 19:57:56 UTC 2018
New revision: 337585
URL: https://svnweb.freebsd.org/changeset/base/337585

Log:
  In r308100, an explicit -fexceptions flag was added for the C sources
  from LLVM's libunwind, which end up in libgcc_eh.a and libgcc_s.so.
  This is because the unwinder needs the unwinder data for its own
  functions.

  However, for the C++ sources in libunwind, -fexceptions is already the
  default, and this can have the side effect of generating a reference to
  __gxx_personality_v0, the so-called personality function, which is
  normally provided by the C++ ABI library (libcxxrt or libsupc++).

  If the reference ends up in the eventual libgcc_s.so, linking any
  non-C++ programs against it will fail with "undefined reference to
  `__gxx_personality_v0'".

  Note that at high optimization levels, the reference is usually
  optimized away, which is why we have never noticed this problem before.

  With clang 7.0.0 though, higher optimization levels don't help anymore,
  since the addition of address-significance tables [1] in
  <https://reviews.llvm.org/rL337339>.  Effectively, this always causes a
  reference to __gxx_personality_v0.

  After discussion with the upstream author of that change, it turns out
  that we should compile libunwind sources with the -fno-exceptions
  -funwind-tables flags instead.  This ensures unwind tables are
  generated, but no references to any personality functions are emitted.

  [1] https://lists.llvm.org/pipermail/llvm-dev/2018-May/123514.html

  Reported by:	jbeich
  PR:		230399
  MFC after:	1 week

Changes:
  head/lib/libgcc_eh/Makefile.inc
Comment 9 Dimitry Andric freebsd_committer freebsd_triage 2018-08-10 22:16:41 UTC
(In reply to commit-hook from comment #8)
> A commit references this bug:
> 
> Author: dim
> Date: Fri Aug 10 19:57:56 UTC 2018
> New revision: 337585
> URL: https://svnweb.freebsd.org/changeset/base/337585
...
>   After discussion with the upstream author of that change, it turns out
>   that we should compile libunwind sources with the -fno-exceptions
>   -funwind-tables flags instead.  This ensures unwind tables are
>   generated, but no references to any personality functions are emitted.

In the clang700-import branch, this fix has now been merged as of r337590.  Please re-test. :)
Comment 10 Kubilay Kocak freebsd_committer freebsd_triage 2018-08-11 01:21:28 UTC
is/will a/the workaround in the port still be required, until base r337585 ends up in -RELEASES?
Comment 11 Dimitry Andric freebsd_committer freebsd_triage 2018-08-11 06:38:02 UTC
(In reply to Kubilay Kocak from comment #10)
> is/will a/the workaround in the port still be required, until base r337585
> ends up in -RELEASES?

Previous releases shouldn't be affected, this problem was only applicable to the clang700-import branch.  (E.g., due to the optimization I described, the __gxx_personality_v0 reference does not end up in libgcc_s.so with previous versions of clang.  It would only affect people who rebuilt their libgcc_s.so by hand, using -O0.)
Comment 13 commit-hook freebsd_committer freebsd_triage 2020-05-04 22:59:52 UTC
A commit references this bug:

Author: dim
Date: Mon May  4 22:59:41 UTC 2020
New revision: 360643
URL: https://svnweb.freebsd.org/changeset/base/360643

Log:
  Merge additions of LLVM libunwind libgcc_eh and libgcc_s. This is in
  preparation of further LLVM merges.

  MFC r307230 (by emaste):

  Introduce lib/libgcc_eh and lib/libgcc_s for LLVM's implementation

  They are not yet connected to the build, but I am adding them to allow
  for easier testing, ports exp-runs, etc.

  Reviewed by:	ed
  Sponsored by:	The FreeBSD Foundation
  Differential Revision:	https://reviews.freebsd.org/D8188

  MFC r307231 (by emaste):

  libgcc_s: add libm dependencies from div{d,s,x}c3

  compiler-rt's complex division support routines contain calls to
  compiler builtins such as `__builtin_scalbnl`.  Unfortunately Clang
  turns these back into a call to `scalbnl`.

  For now link libm's C version of the required support routines.

  Reviewed by:	ed
  Sponsored by:	The FreeBSD Foundation
  Differential Revision:	https://reviews.freebsd.org/D8190

  MFC r307864 (by emaste):

  Move the LLVM-based libgcc_s to /lib

  When enabled, it should install in the same location as the existing
  library.

  Reported by:	antoine

  MFC r308001 (by emaste):

  libgcc_eh/libgcc_s: apply hidden visibility only to static libs

  MFC r308100 (by emaste):

  compile libunwind c source with -fexceptions

  When an exception is thrown the unwinder must unwind its own C source
  (starting with _Unwind_RaiseException in UnwindLevel1.c), so it needs to
  be built with unwinding data.

  MFC r308294 (by emaste):

  libgcc_s: make unspecified shlib symbols local

  We want only symbols explicitly specified in the Version.map.

  Sponsored by:	The FreeBSD Foundation

  MFC r308308 (by emaste):

  Connect new LLVM-based libgcc_eh & libgcc_s to the build

  Compiler-rt and LLVM's libunwind provide a suitable replacement for
  libgcc.a, libgcc_eh.a, and libgcc_s.so.

  Remove the now-unused LLVM_LIBUNWIND block from gnu/lib/libgcc.

  PR:		213480 [exp-run]
  Reviewed by:	brooks, ed
  Sponsored by:	The FreeBSD Foundation
  Differential Revision:	https://reviews.freebsd.org/D8189

  MFC r308379 (by emaste):

  add __divdi3 and __udivdi3 to libgcc_s symbol version map

  After r308294 they were missing on i386 (and previously were exported
  only accidentally).

  Reported by:	antoine

  MFC r308445 (by emaste):

  add missing i386 symbols libgcc_s symbol version map

  After r308294 they were missing on i386 (and previously were exported
  only accidentally).

  Reported by:	antoine

  MFC r312076 (by emaste):

  libgcc_s: add libc DT_NEEDED to fix underlinking

  PR:		216012
  Reported by:	jbeich
  Sponsored by:	The FreeBSD Foundation

  MFC r316101 (by ngie):

  Apply r315689 to lib/libgcc_s as well to unbreak the gcc xtoolchain build

  lib/libgcc_s consumes lib/libcompiler_rt/Makefile*. The NO_WERROR.gcc in
  lib/libcompiler_rt/Makefile doesn't seem to have made a difference in being
  able to build this, so sprinkle NO_WERROR.gcc here as well.

  Reported by:	Jenkins (FreeBSD-head-amd64-gcc)
  Tested with:	amd64-gcc-6.3.0 (devel/amd64-xtoolchain-gcc)
  Sponsored by:	Dell EMC Isilon

  MFC r320673 (by emaste):

  Sort entries in libgcc_s Version.map

  MFC r337585 (by dim):

  In r308100, an explicit -fexceptions flag was added for the C sources
  from LLVM's libunwind, which end up in libgcc_eh.a and libgcc_s.so.
  This is because the unwinder needs the unwinder data for its own
  functions.

  However, for the C++ sources in libunwind, -fexceptions is already the
  default, and this can have the side effect of generating a reference to
  __gxx_personality_v0, the so-called personality function, which is
  normally provided by the C++ ABI library (libcxxrt or libsupc++).

  If the reference ends up in the eventual libgcc_s.so, linking any
  non-C++ programs against it will fail with "undefined reference to
  `__gxx_personality_v0'".

  Note that at high optimization levels, the reference is usually
  optimized away, which is why we have never noticed this problem before.

  With clang 7.0.0 though, higher optimization levels don't help anymore,
  since the addition of address-significance tables [1] in
  <https://reviews.llvm.org/rL337339>.  Effectively, this always causes a
  reference to __gxx_personality_v0.

  After discussion with the upstream author of that change, it turns out
  that we should compile libunwind sources with the -fno-exceptions
  -funwind-tables flags instead.  This ensures unwind tables are
  generated, but no references to any personality functions are emitted.

  [1] https://lists.llvm.org/pipermail/llvm-dev/2018-May/123514.html

  Reported by:	jbeich
  PR:		230399

Changes:
_U  stable/11/
  stable/11/Makefile.inc1
  stable/11/gnu/lib/Makefile
  stable/11/gnu/lib/libgcc/Makefile
  stable/11/lib/Makefile
  stable/11/lib/libgcc_eh/
  stable/11/lib/libgcc_eh/Makefile.inc
  stable/11/lib/libgcc_s/
  stable/11/lib/libgcc_s/Makefile
  stable/11/lib/libgcc_s/Version.map