GPL requirements vs. "some of which are compiled with GCC" terms in special exceptions?

Mark Millard marklmi at yahoo.com
Tue Oct 16 16:15:13 UTC 2018


[WITH_LLVM_LIBUNWIND= is still broken for powerpc64
(and likely powerpc).]

On 2018-Oct-13, at 7:54 PM, Mark Millard <marklmi at yahoo.com> wrote:

> On 2018-Oct-13, at 7:40 PM, Mark Millard <marklmi at yahoo.com> wrote:
> 
>> On 2018-Oct-13, at 10:15 AM, David Chisnall <theraven at FreeBSD.org> wrote:
>> 
>>> This is a known problem with the GCC runtime libraries.  GCC 4.3 and later have a much better exemption (which talks about any eligible compilation process, rather than being compiled with GCC), but those are GPLv3 and so unacceptable for FreeBSD.
>> 
>> I see. Good to know.
> 
> Hmm. As of head -r339076 the src.conf man page says:
> 
>     WITHOUT_LLVM_LIBUNWIND
>             Set to use GCC's stack unwinder (instead of LLVM's libunwind).
> 
>             This is a default setting on arm/arm, arm/armv6, arm/armv7,
>             powerpc/powerpc, powerpc/powerpc64, powerpc/powerpcspe and
>             sparc64/sparc64.
> 
> I believe arm/armv7, arm/armv6, and arm/arm are using clang for such
> vintages:
> 
>     WITH_CLANG_BOOTSTRAP
>             Set to build the Clang C/C++ compiler during the bootstrap phase
>             of the build.
> 
>             This is a default setting on amd64/amd64, arm/arm, arm/armv6,
>             arm/armv7, arm64/aarch64 and i386/i386.
> 
> 
> But may be the man page is just out of date for WITHOUT_LLVM_LIBUNWIND ?
> 
>>> I don’t believe that we are using any of those files on platforms where clang is the default system compiler.  LLVM’s libUnwind should be able to handle PowerPC on Linux, so it’s worth checking if this is the case on FreeBSD.
>> 
>> Last I tried llvm's libunwind for powerpc64 was back in 2016-Dec/2017-Jan.
>> See https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=215039 . There was also
>> the llvm submittal 31590.
>> 
>> I might try it again at some point. But clang and llvm have other issues for
>> use for buildworld buildkernel as well as I understand. (But I'm doing some
>> new experiments these days.)
>> 
>> I've no clue if llvm's libunwind is intended to be compliant with the
>> powerpc64 and powerpc ABIs that FreeBSD bases itself on for the powerpc
>> family.
>> 
>>>> On 13 Oct 2018, at 18:12, Mark Millard via freebsd-toolchain <freebsd-toolchain at freebsd.org> wrote:
>>>> 
>>>> While investigating powerpc64 C++ exception handling for
>>>> builds under devel/powerpc64-gcc I ran into the following
>>>> in /usr/src/contrib/gcc/unwind-dw2-fde-glibc.c :
>>>> 
>>>> /* As a special exception, if you link this library with other files,
>>>> some of which are compiled with GCC, to produce an executable,
>>>> this library does not by itself cause the resulting executable
>>>> to be covered by the GNU General Public License.
>>>> This exception does not however invalidate any other reasons why
>>>> the executable file might be covered by the GNU General Public License.  */
>>>> 
>>>> So in contexts were clang/llvm is used to exclusion . . . are
>>>> any such files in use? (I happen to be using devel/powerpc64-gcc at
>>>> the moment.)
>>>> 
>>>> For me this has no real implications: I do not distribute
>>>> my experiments. But I was surprised by what I read.
>>>> 
>>>> Looking I find:
>>>> 
>>>> # grep -r "some of which are compiled with GCC" /usr/src/* | more
>>>> /usr/src/contrib/gcc/config/i386/gthr-win32.c:   some of which are compiled with GCC, to produce an executable,
>>>> /usr/src/contrib/gcc/config/ia64/crtend.asm:   some of which are compiled with GCC, to produce an executable,
>>>> /usr/src/contrib/gcc/config/ia64/fde-glibc.c:   some of which are compiled with GCC, to produce an executable,
>>>> /usr/src/contrib/gcc/config/ia64/crtbegin.asm:   some of which are compiled with GCC, to produce an executable,
>>>> /usr/src/contrib/gcc/config/ia64/lib1funcs.asm:   some of which are compiled with GCC, to produce an executable,
>>>> /usr/src/contrib/gcc/config/ia64/crtfastmath.c:   some of which are compiled with GCC, to produce an executable,
>>>> /usr/src/contrib/gcc/config/ia64/unwind-ia64.c:   some of which are compiled with GCC, to produce an executable,
>>>> /usr/src/contrib/gcc/config/mips/mips16.S:   some of which are compiled with GCC, to produce an executable,
>>>> /usr/src/contrib/gcc/config/vxlib.c:   some of which are compiled with GCC, to produce an executable,
>>>> /usr/src/contrib/gcc/libgcc2.h:   some of which are compiled with GCC, to produce an executable,
>>>> /usr/src/contrib/gcc/gthr-posix95.h:   some of which are compiled with GCC, to produce an executable,
>>>> /usr/src/contrib/gcc/gthr-posix.h:   some of which are compiled with GCC, to produce an executable,
>>>> /usr/src/contrib/gcc/gthr-posix.c:   some of which are compiled with GCC, to produce an executable,
>>>> /usr/src/contrib/gcc/gbl-ctors.h:   some of which are compiled with GCC, to produce an executable,
>>>> /usr/src/contrib/gcc/gthr-gnat.c:   some of which are compiled with GCC, to produce an executable,
>>>> /usr/src/contrib/gcc/gthr-rtems.h:   some of which are compiled with GCC, to produce an executable,
>>>> /usr/src/contrib/gcc/gthr-vxworks.h:   some of which are compiled with GCC, to produce an executable,
>>>> /usr/src/contrib/gcc/gthr-dce.h:   some of which are compiled with GCC, to produce an executable,
>>>> /usr/src/contrib/gcc/gthr-nks.h:   some of which are compiled with GCC, to produce an executable,
>>>> /usr/src/contrib/gcc/gthr-tpf.h:   some of which are compiled with GCC, to produce an executable,
>>>> /usr/src/contrib/gcc/gthr-aix.h:   some of which are compiled with GCC, to produce an executable,
>>>> /usr/src/contrib/gcc/gthr-lynx.h:   some of which are compiled with GCC, to produce an executable,
>>>> /usr/src/contrib/gcc/gthr-solaris.h:   some of which are compiled with GCC, to produce an executable,
>>>> /usr/src/contrib/gcc/gthr.h:   some of which are compiled with GCC, to produce an executable,
>>>> /usr/src/contrib/gcc/gcov-io.h:   some of which are compiled with GCC, to produce an executable,
>>>> /usr/src/contrib/gcc/gthr-gnat.h:   some of which are compiled with GCC, to produce an executable,
>>>> /usr/src/contrib/gcc/gthr-single.h:   some of which are compiled with GCC, to produce an executable,
>>>> /usr/src/contrib/gcc/gthr-win32.h:   some of which are compiled with GCC, to produce an executable,
>>>> /usr/src/contrib/gcc/tsystem.h:   some of which are compiled with GCC, to produce an executable,
>>>> /usr/src/contrib/gcc/typeclass.h:   some of which are compiled with GCC, to produce an executable,
>>>> /usr/src/contrib/gcc/unwind-dw2-fde-glibc.c:   some of which are compiled with GCC, to produce an executable,
>>>> /usr/src/contrib/gcc/unwind-dw2-fde-darwin.c:   some of which are compiled with GCC, to produce an executable,
>>> 
> 

As for using WITH_LLVM_LIBUNWIND= for powerpc64 with devel/powerpc64-gcc
based on the current build infrastructure and the notation in some
of the files (simply adding the line to my alternately-named equivalent
of src.conf for such a build):

. . .
GNU C99 (FreeBSD Ports Collection for powerpc64) version 6.4.0 (powerpc64-unknown-freebsd12.0)
	compiled by GNU C version 4.2.1 Compatible FreeBSD Clang 6.0.1 (tags/RELEASE_601/final 335540), GMP version 6.1.2, MPFR version 4.0.1, MPC version 1.1.0, isl version none
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
. . .
--- UnwindRegistersRestore.o ---
Using built-in specs.
COLLECT_GCC=/usr/local/bin/powerpc64-unknown-freebsd12.0-gcc
Target: powerpc64-unknown-freebsd12.0
Configured with: /wrkdirs/usr/ports/devel/powerpc64-gcc/work/gcc-6.4.0/configure --target=powerpc64-unknown-freebsd12.0 --disable-nls --enable-languages=c,c++ --enable-gnu-indirect-function --without-headers --with-gmp=/usr/local --with-pkgversion='FreeBSD Ports Collection for powerpc64' --with-system-zlib --with-gxx-include-dir=/usr/include/c++/v1/ --with-sysroot=/ --with-as=/usr/bin/powerpc64-unknown-freebsd12.0-as --with-ld=/usr/bin/powerpc64-unknown-freebsd12.0-ld --enable-initfini-array --prefix=/usr/local --localstatedir=/var --mandir=/usr/local/man --infodir=/usr/local/info/ --build=powerpc64-unknown-freebsd12.0
Thread model: posix
gcc version 6.4.0 (FreeBSD Ports Collection for powerpc64) 
COLLECT_GCC_OPTIONS='-gdwarf-2' '-B' '/usr/local/powerpc64-unknown-freebsd12.0/bin/' '-O2' '-pipe' '-I' '/usr/src/contrib/llvm/projects/libunwind/include' '-I' '/usr/src/lib/libgcc_eh' '-D' '_LIBUNWIND_IS_NATIVE_ONLY' '-g' '-std=gnu99' '-Wsystem-headers' '-Wall' '-Wno-format-y2k' '-Wno-uninitialized' '-Wno-pointer-sign' '-Wno-error=address' '-Wno-error=array-bounds' '-Wno-error=attributes' '-Wno-error=bool-compare' '-Wno-error=cast-align' '-Wno-error=clobbered' '-Wno-error=enum-compare' '-Wno-error=extra' '-Wno-error=inline' '-Wno-error=logical-not-parentheses' '-Wno-error=strict-aliasing' '-Wno-error=uninitialized' '-Wno-error=unused-but-set-variable' '-Wno-error=unused-function' '-Wno-error=unused-value' '-Wno-error=misleading-indentation' '-Wno-error=nonnull-compare' '-Wno-error=shift-negative-value' '-Wno-error=tautological-compare' '-Wno-error=unused-const-variable' '-v' '-c' '-o' 'UnwindRegistersRestore.o'
. . .
--- UnwindRegistersRestore.o ---
ignoring nonexistent directory "/usr/local/lib/gcc/powerpc64-unknown-freebsd12.0/6.4.0/include-fixed"
ignoring nonexistent directory "/usr/local/lib/gcc/powerpc64-unknown-freebsd12.0/6.4.0/../../../../powerpc64-unknown-freebsd12.0/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/src/contrib/llvm/projects/libunwind/include
 /usr/src/lib/libgcc_eh
 /usr/local/lib/gcc/powerpc64-unknown-freebsd12.0/6.4.0/include
 /usr/obj/powerpc64vtsc_xtoolchain-gcc/powerpc.powerpc64/usr/src/powerpc.powerpc64/tmp/usr/include
End of search list.
. . .
--- UnwindRegistersRestore.o ---
/usr/src/contrib/llvm/projects/libunwind/src/UnwindRegistersRestore.S: Assembler messages:
/usr/src/contrib/llvm/projects/libunwind/src/UnwindRegistersRestore.S:98: Error: junk at end of line, first unrecognized character is `@'
/usr/src/contrib/llvm/projects/libunwind/src/UnwindRegistersRestore.S:98: Error: junk at end of line, first unrecognized character is `@'
/usr/src/contrib/llvm/projects/libunwind/src/UnwindRegistersRestore.S:100: Error: unrecognized opcode: `void'
/usr/src/contrib/llvm/projects/libunwind/src/UnwindRegistersRestore.S:102: Error: unrecognized opcode: `on'
/usr/src/contrib/llvm/projects/libunwind/src/UnwindRegistersRestore.S:103: Error: unrecognized opcode: `thread_state'
/usr/src/contrib/llvm/projects/libunwind/src/UnwindRegistersRestore.S:106: Error: unrecognized opcode: `restore'
/usr/src/contrib/llvm/projects/libunwind/src/UnwindRegistersRestore.S:107: Error: unrecognized opcode: `skip'
/usr/src/contrib/llvm/projects/libunwind/src/UnwindRegistersRestore.S:108: Error: unrecognized opcode: `skip'
/usr/src/contrib/llvm/projects/libunwind/src/UnwindRegistersRestore.S:110: Error: unrecognized opcode: `skip'
. . .

(I will not list the long list of errors.)

It appears that the file expects C-preprocessor handling that
is not applied (#lines not treated as comments, #if defined(...)
ignored):

//===-------------------- UnwindRegistersRestore.S ------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "assembly.h"

  .text

#if defined(__i386__)
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_x866jumptoEv)
#
# void libunwind::Registers_x86::jumpto()
#
# On entry:
#  +                       +
#  +-----------------------+
#  + thread_state pointer  +
#  +-----------------------+
#  + return address        +
#  +-----------------------+   <-- SP
#  +                       +
  movl   4(%esp), %eax
  # set up eax and ret on new stack location
  movl  28(%eax), %edx # edx holds new stack pointer
  subl  $8,%edx
  movl  %edx, 28(%eax)
  movl  0(%eax), %ebx
  movl  %ebx, 0(%edx)
  movl  40(%eax), %ebx
  movl  %ebx, 4(%edx)
  # we now have ret and eax pushed onto where new stack will be
  # restore all registers
  movl   4(%eax), %ebx
  movl   8(%eax), %ecx
  movl  12(%eax), %edx
  movl  16(%eax), %edi
  movl  20(%eax), %esi
  movl  24(%eax), %ebp
  movl  28(%eax), %esp
  # skip ss
  # skip eflags
  pop    %eax  # eax was already pushed on new stack
  ret        # eip was already pushed on new stack
  # skip cs
  # skip ds
  # skip es
  # skip fs
  # skip gs

. . .

There is also the oddity of the __ppc__ code's notation:

#elif defined(__ppc__)

DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_ppc6jumptoEv)
;
; void libunwind::Registers_ppc::jumpto()
;
; On entry:
;  thread_state pointer is in r3
;

  ; restore integral registerrs
  ; skip r0 for now
  ; skip r1 for now
  lwz     r2, 16(r3)
  ; skip r3 for now
  ; skip r4 for now
  ; skip r5 for now
  lwz     r6, 32(r3)
  lwz     r7, 36(r3)
  lwz     r8, 40(r3)
  lwz     r9, 44(r3)
  lwz    r10, 48(r3)
  lwz    r11, 52(r3)
  lwz    r12, 56(r3)
  lwz    r13, 60(r3)
. . .

Justin Hibbits wrote about this notation
( https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=215039
comment 1 ):

QUOTE
The naked 'r*' and 'f*' register designations are a Darwinism.  SysV notation requires '%r*' and '%f*', or naked numbers.

This should probably be filed upstream as well.
END QUOTE

This suggests that, for __ppc__, LLVM's libunwind is Darwin specific
still.

===
Mark Millard
marklmi at yahoo.com
( dsl-only.net went
away in early 2018-Mar)



More information about the freebsd-toolchain mailing list