Bug 230399 - devel/libunwind: fails to build with Clang 7
Summary: devel/libunwind: fails to build with Clang 7
Status: Closed FIXED
Alias: None
Product: Ports & Packages
Classification: Unclassified
Component: Individual Port(s) (show other bugs)
Version: Latest
Hardware: Any Any
: --- Affects Only Me
Assignee: freebsd-toolchain mailing list
URL:
Keywords: needs-qa, toolchain
Depends on:
Blocks: 230355
  Show dependency treegraph
 
Reported: 2018-08-06 00:12 UTC by Jan Beich
Modified: 2018-08-13 20:55 UTC (History)
5 users (show)

See Also:
koobs: merge-quarterly?


Attachments
workaround (361 bytes, patch)
2018-08-06 16:32 UTC, Jan Beich
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jan Beich freebsd_committer 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 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 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 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 2018-08-06 16:32:30 UTC
Created attachment 195944 [details]
workaround
Comment 5 Dimitry Andric freebsd_committer 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 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 2018-08-09 20:42:13 UTC
Reported upstream: https://bugs.llvm.org/show_bug.cgi?id=38506
Comment 8 commit-hook freebsd_committer 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 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 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.)