Summary: | ar cannot handle (slim) LTO object files when in MRI script mode | ||
---|---|---|---|
Product: | binutils | Reporter: | Martin Schulze <spam.martin.schulze> |
Component: | binutils | Assignee: | Not yet assigned to anyone <unassigned> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | 12f8219, nickc |
Priority: | P2 | ||
Version: | 2.28 | ||
Target Milestone: | --- | ||
Host: | Target: | ||
Build: | Last reconfirmed: | 2017-08-01 00:00:00 | |
Attachments: |
Example project that exhibits the problem
Proposed patch Proposed patch |
I just noticed that the problem is reproducible with "normal" ar. Hi Martin, This is a build/system installation issue more than anything. Assuming that ar has been configured with --enable-plugins set[1] then the problem is that ar is not finding the plugin that it needs. They are two ways that it can find the plugin. The first is via a command line option to ar itself, vis: --plugin=<path-to-gcc-lto-plugin>. This is the better solution, IMHO, although it does mean that you will have to update your build framework. The second method is that ar (and the other binutils that support plugins) will look in the directory /usr/lib/bfd-plugins for the plugin. So if you copy gcc's liblto_plugin into this directory everything should start to work. I am not a fan of this method since it relies upon having admin access on the build machine, and it is easy to forget that the directory is there, and then have problems because an out of date plugin is being used. Cheers Nick [1] I am not familiar with Arch Linux, but I suspect that plugin support is probably enabled. Most distributions do that now. Hi Nick, thanks for your reply. Yes, Arch compiles with --enable-plugins. Otherwise the linking while using the command line (ar rcs ...) wouldn't work too. I already tried to add the --plugin option to no avail. Furthermore, Arch's gcc package defaults to creating the symlink /usr/lib/bfd-plugins/liblto_plugin.so -> /usr/lib/gcc/x86_64-pc-linux-gnu/7.1.1/liblto_plugin.so so it should also be found via this method (as it seems to be with the `ar rcs ...` call). I think the problem is that the plugin is not loaded in MRI mode where it should be. This is illustrated nicely by the fact that following call works as expected (without any plugin option): ar rcs libfunc.non-mri.a func.o While these two both give an error: ar -M < mri_script ar: func.o: plugin needed to handle lto object ar --plugin=/usr/lib/gcc/x86_64-pc-linux-gnu/7.1.1/liblto_plugin.so -M < mri_script ar: func.o: plugin needed to handle lto object Created attachment 10298 [details] Proposed patch Hi Martin, Ah - I was confused by comment #1 which made me think that the problem also applied in non-MRI mode. Anyway, please can you try out this patch and let me know if it works for you. I am not an MRI expert, but I suspect that the patch might need to be extended to cope with other things that can be done with MRI scripts. If you find anything like this please let me know. Cheers Nick Sorry about the confusion, I see now that it was worded ambiguously. I tried the patch and it works. The master branch has been updated by Nick Clifton <nickc@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=70b0cf90bc6c071895b989666bcf3e6eca7b99ce commit 70b0cf90bc6c071895b989666bcf3e6eca7b99ce Author: Nick Clifton <nickc@redhat.com> Date: Wed Aug 2 12:12:37 2017 +0100 Add support for creating archives of slim-LTO modules using MRi script commands. PR 21702 * arsup.c (ar_addmod): Add plugin support for the MRI ADDMOD command. Hi Martin, OK - I have applied the patch. If more problems like this arise, please feel free to reopen this PR, or create a new one. Cheers Nick I'll keep my eyes open. Thanks for the fast solution. .root@h Xext 0# ar crs .libs/libXext.a .libs/bigreq.o .libs/geext.o .libs/shape.o .libs/sleepuntil.o .libs/sync.o .libs/xcmisc.o .libs/xtest.o .libs/shm.o .libs/xvmain.o .libs/xvdisp.o .libs/xvmc.o .libs/xres.o .libs/dpms.o .root@h Xext 0# ar tv .libs/libXext.a rw-r--r-- 0/0 23104 Jan 1 02:00 1970 bigreq.o rw-r--r-- 0/0 68008 Jan 1 02:00 1970 geext.o rw-r--r-- 0/0 211184 Jan 1 02:00 1970 shape.o rw-r--r-- 0/0 37032 Jan 1 02:00 1970 sleepuntil.o rw-r--r-- 0/0 424360 Jan 1 02:00 1970 sync.o rw-r--r-- 0/0 45368 Jan 1 02:00 1970 xcmisc.o rw-r--r-- 0/0 211632 Jan 1 02:00 1970 xtest.o rw-r--r-- 0/0 278704 Jan 1 02:00 1970 shm.o rw-r--r-- 0/0 218928 Jan 1 02:00 1970 xvmain.o rw-r--r-- 0/0 358776 Jan 1 02:00 1970 xvdisp.o rw-r--r-- 0/0 184584 Jan 1 02:00 1970 xvmc.o rw-r--r-- 0/0 157936 Jan 1 02:00 1970 xres.o rw-r--r-- 0/0 110824 Jan 1 02:00 1970 dpms.o .root@h Xext 0# ar -M <<EOF OPEN .libs/libXext.a SAVE END EOF /usr/lib/gcc/x86_64-gentoo-linux-musl/10.2.0/../../../../x86_64-gentoo-linux-musl/bin/ar: .libs/libXext.a(bigreq.o): plugin needed to handle lto object (In reply to Pavel from comment #9) Hi Pavel, Please can you see if it is possible to reduce the list of object files a little bit, and then upload them so that I can run some tests ? Cheers Nick (In reply to Nick Clifton from comment #10) > (In reply to Pavel from comment #9) > Hi Pavel, > > Please can you see if it is possible to reduce the list of object files a > little bit, and then upload them so that I can run some tests ? > > Cheers > Nick #!/bin/sh readlink -f /usr/bin/ar echo 'int main() {return 0;}' > t.c set -x gcc -flto -c t.c /usr/bin/ar crsv l.a t.o echo ' open l.a list end' | /usr/bin/ar -M echo ' open l.a save end' | /usr/bin/ar -M gcc -flto -fuse-linker-plugin l.a -o t (In reply to Pavel from comment #12) Sorry, I am not quite sure what to do with these files. I tried this: % ar --plugin=/usr/lib64/bfd-plugins/liblto_plugin.so -M AR >open -AbO.a AR >save AR >end There were no error messages about missing plugins. Note - this was with the latest version of ar built from today's mainline binutils sources. When I used the system version of ar, I did get the error message: % /usr/bin/ar --plugin=/usr/lib64/bfd-plugins/liblto_plugin.so -M AR >open -AbO.a AR >save /usr/bin/ar: -AbO.a(t.o): plugin needed to handle lto object AR >end Cheers Nick sorry, i dont know what today mainline version is, but 2.36.1 also fails: /var/tmp/portage/sys-devel/binutils-2.36.1/image/usr/x86_64-gentoo-linux-musl/binutils-bin/2.36.1/ar --plugin /usr/lib/bfd-plugins/liblto_plugin.so -M /var/tmp/portage/sys-devel/binutils-2.36.1/image/usr/x86_64-gentoo-linux-musl/binutils-bin/2.36.1/ar: l.a(t.o): plugin needed to handle lto object Created attachment 13378 [details]
Proposed patch
Ah ha - I think that I have it. Please could you try this uploaded patch ?
(In reply to Nick Clifton from comment #15) > Created attachment 13378 [details] > Proposed patch > > Ah ha - I think that I have it. Please could you try this uploaded patch ? yep. this patch fixes it. i never would have guessed that problem is not in 'save' or 'write' but in 'open'. The master branch has been updated by Nick Clifton <nickc@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=229597a129f62d5e8a101f1eed95489e2399f741 commit 229597a129f62d5e8a101f1eed95489e2399f741 Author: Nick Clifton <nickc@redhat.com> Date: Mon Apr 19 17:38:39 2021 +0100 Fix a problem running the archiver program in MRI mode on archives containing LTO compiled objects. PR 21702 * arsup.c (ar_addmod): Enable plugin support, if available. It did take a bit of tracking down, but I am glad that I found it in the end. Patch applied. |
Created attachment 10239 [details] Example project that exhibits the problem This problem turned up while cross-compiling Qt 5.9.0 with LTO enabled. ar gives the error "plugin needed to handle lto object" and generates an output file which results in undefined reference errors when linked. You can reproduce this by running make in the attached project tree. (Obviously you need x86_64-w64-mingw32-{ar,gcc} for this to work.) The run will result in the aformentioned errors instead of a successfully built binary. The output is as follows: $ make x86_64-w64-mingw32-gcc -c -flto -o func.o func.c x86_64-w64-mingw32-ar -M < mri_script x86_64-w64-mingw32-ar: func.o: plugin needed to handle lto object x86_64-w64-mingw32-gcc -flto main.c -o main -L. -lfunc /tmp/cc7mkhTU.ltrans0.ltrans.o:<artificial>:(.text+0x1b): undefined reference to `func' /tmp/cc7mkhTU.ltrans0.ltrans.o:<artificial>:(.text+0x22): undefined reference to `func2' I also added a make target main.non-mri that uses command line parameters for ar instead of the mri script. This invocation works as expected and builts an executable that can be run via wine. Additional Information: I am running this on Arch Linux 64bit: $ x86_64-w64-mingw32-ar --version GNU ar (GNU Binutils) 2.28 I did not post this on MinGW bugtracker as they seem to only handle bugs under Windows and this is a cross-compilation problem. I also decided against the GCC bugtracker as this seems to be a problem with the archiver.