Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

lld can't handle gcc LTO files #41416

Open Quuxplusone opened 5 years ago

Quuxplusone commented 5 years ago
Bugzilla Link PR42446
Status NEW
Importance P enhancement
Reported by Bernhard Rosenkraenzer (bero@lindev.ch)
Reported on 2019-06-29 13:59:52 -0700
Last modified on 2021-10-18 19:42:16 -0700
Version unspecified
Hardware PC Linux
CC arthur200126@gmail.com, davispuh@gmail.com, dblaikie@gmail.com, i@maskray.me, ivan@nisavid.io, llvm-bugs@lists.llvm.org, mail@milianw.de, mati865@gmail.com, romain.geissler@amadeus.com, ruiu@google.com, sam@gentoo.org, smithp352@googlemail.com, tstellar@redhat.com
Fixed by commit(s)
Attachments
Blocks
Blocked by
See also
lld tends to works well with clang LTO files and gcc non-LTO files these days,
but can't it can't handle gcc LTO:

$ cat test.c
#include <stdio.h>
int main(int argc, char **argv) {
        puts("test");
}
$ clang -fuse-ld=lld -flto test.c && echo good
good
$ gcc -fuse-ld=bfd -flto test.c && echo good
good
$ gcc -fuse-ld=lld test.c && echo good
good
$ gcc -fuse-ld=lld -flto test.c && echo good
ld.lld: error: undefined symbol: main
>>> referenced by start.S:110 (../sysdeps/x86_64/start.S:110)
>>>               /usr/lib64/gcc/x86_64-openmandriva-linux-
gnu/9.1.1/../../../../lib64/crt1.o:(_start)
collect2: error: ld returned 1 exit status
Quuxplusone commented 5 years ago

LLD supports LLVM LTO by including the code generator in the executable, whereas ld.bfd and ld.gold have a plugin mechanism permitting clang, gcc and in theory other compilers to support LTO via a shared object.

I'm not aware of any plans to support a plugin mechanism for LLD at the moment; so if I'm right, apologies this isn't likely to change any time soon.

Quuxplusone commented 5 years ago

It is very unlikely that we will support GCC's LTO files, but it may be a good idea to print out a user-friendly error messages to tell the user that lld does not support GCC's LTO files when the linker sees them as input files.

Quuxplusone commented 4 years ago
Hi,

Are there still no plan for now to support a similar bfd/gold plugin API ?

Cheers,
Romain
Quuxplusone commented 4 years ago

Plugin is inherently hacky, so I'd like to stick with directly supporting LLVM.

Quuxplusone commented 4 years ago
(In reply to Rui Ueyama from comment #4)
> Plugin is inherently hacky, so I'd like to stick with directly supporting
> LLVM.

While I'm not necessarily in favor of adding a plugin API To lldb I don't find
plugins to be "inherently hacky" - actually keeping the linker and compiler
functionality (even for LTO) separated & "pluginable" seems nicer to me in some
ways than a linker hardcoding/linking to a specific compiler implementation.

Perhaps you could describe more what you mean/find to be especially problematic
about supporting a plugin architecture. (I think it's complexity probably not
worth the addition in this case - but I don't think it's /inherently/ wrong)
Quuxplusone commented 4 years ago

You can add hook points to your program and define a clear API to provide a plugin mechanism, but what I often observe is that people tend to push the plugin mechanism too much, especially when the boundary the plugin API provides doesn't fit well to what they want to do, and as a result programs tend to become hairly. In addition to that, adding a plugin mechanism to your program makes you think more when making a code change, as plugin can do a lot of things but you can't see the code.

Of course it is not always the case, but I'd like to see a strong reasoning to add a plugin mechanism if we add one. Speaking of this specific case, since we already support LLVM LTO very elegantly, supporting GCC LTO doesn't seem like a strong reason to add a plugin mechanism to lld.

Quuxplusone commented 4 years ago
Hi,

I don't know at all the internals of lld. You write that you support "support
LLVM LTO very elegantly", however I have no idea how that mechanism is written.
How is that implemented (just the high level view) ? And if we were to do the
same for GCC LTO, what would be needed so that it happens ? I guess somehow
that would require that the gcc project itself export some kind of library that
would be used to link lld with ?

Cheers,
Romain
Quuxplusone commented 4 years ago
(In reply to Romain Geissler from comment #7)
> Hi,
>
> I don't know at all the internals of lld. You write that you support
> "support LLVM LTO very elegantly", however I have no idea how that mechanism
> is written.

Direct API usage - lld links to llvm & calls into its C++ API to perform LTO,
etc.

> How is that implemented (just the high level view) ? And if we
> were to do the same for GCC LTO, what would be needed so that it happens ? I
> guess somehow that would require that the gcc project itself export some
> kind of library that would be used to link lld with ?

Yeah, though I'm not sure anyone would be particularly comfortable with lld
taking (even an optional) dependency on gcc. But I'm not a major lld
contributor, so I'd leave that up to the lld folks. It's probably the sort of
thing you might contain in an lld fork downstream & could probably provide
patches in favor of a tidier boundary between lld and the LTO backend (not
exactly a plugin API, but a fairly well secured/isolated boundary so it's
easier to implement a downstream fork with a GCC implementation).
Quuxplusone commented 4 years ago

The thing is, the only stable API the gcc LTO backend comes with today is the plugin api used by GNU ld/gold. And I guess people on the gcc side will most likely say it's a well defined API, which lld could just call. Beyond that, there is no "libgcclto" contrary to what you may have on LLVM side. Some might argue that the gcc people are wrong and shall expose such a lib with such a stable API, but I don't think that's going to ever change.

On technical ground, I still don't really see why one would be against re-using the existing linker plugin API. Even more as you write yourself that even if libgcclto did exist, lld folks would most likely be reluctant to (optionally) depend on that. I do share with you the concern that far too often developers are coming with the idea of plugins to wrongly fix problems at the wrong place, but in that case I really do see an added value to separate linker business from compiler business.

On legal ground though, even if there was someone willing to implement linker plugin support in lld (or in a downstream fork of it), one big question remains: is there any licence exception in the GPLv3 gcc LTO plugin that would allow it to be used from a non GPL linker like lld ? I am not a lawyer, but I think that the LLVM licence is not GPL compatible, and as soon as plugins are concerned GNU folks have always insisted on the compatibility of the licence used alongside GNU ld/gcc code.

Quuxplusone commented 4 years ago

It seems that this is preventing to build systemd using lld [1] When compiling with gcc and lld then it fails with

[556/1950] Linking target systemd-run-generator
FAILED: systemd-run-generator 
cc  -o systemd-run-generator 'systemd-run-generator@exe/src_run-generator_run-generator.c.o' -flto -Wl,--as-needed -Wl,--no-undefined -pie -Wl,-z,relro -Wl,-z,now -fstack-protector -Wl,--gc-sections -march=native -O2 -pipe -fno-plt -fuse-ld=lld -g -fvar-tracking-assignments -fdebug-prefix-map=/mnt/AUR/systemd-git/src=/usr/src/debug -Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now -Wl,--start-group src/shared/libsystemd-shared-245.so -Wl,--end-group '-Wl,-rpath,$ORIGIN/src/shared' -Wl,-rpath-link,/mnt/AUR/systemd-git/src/build/src/shared
ld.lld: error: undefined symbol: main
>>> referenced by init.c
>>>               /usr/lib/gcc/x86_64-pc-linux-gnu/9.3.0/../../../../lib/Scrt1.o:(_start)
collect2: error: ld returned 1 exit status

clang with lld builds fine.

[1] https://github.com/systemd/systemd/issues/15428

Quuxplusone commented 4 years ago
> is there any licence exception in the GPLv3 gcc LTO plugin

No, but...

> I am not a lawyer, but I think that the LLVM licence is not GPL compatible,

LLVM has switched to Apache License 2.0 (with exception) since 9.0.0 (2019), so
it is GPL compatible now. This should open up the option of building a GPL
version of LLD with that functionality, just like FFmpeg has done for its
codecs. On the CMake configuration side, this may take the form of:

* An LLVM_ENABLE_GPL option that allows for a GPL build
* An LLVM_ENABLE_LLD_BFD_PLUGIN option that actually controls the feature

When some GPL feature is ON but the main GPL switch is OFF, the CMake script
should error out and throw up some legal advice.

* * *

A bit into the specifics... I don't think binutils installs a plugin-api.h, so
that file (GPLv3) will need to be copied from binutils to LLVM.

I have no idea what changes are required to the license headers in LLD. Maybe
adding some "OR" clause to the SPDX stuff will do?