Bug 21702

Summary: ar cannot handle (slim) LTO object files when in MRI script mode
Product: binutils Reporter: Martin Schulze <spam.martin.schulze>
Component: binutilsAssignee: 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

Description Martin Schulze 2017-07-03 14:06:59 UTC
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.
Comment 1 Martin Schulze 2017-07-05 11:51:57 UTC
I just noticed that the problem is reproducible with "normal" ar.
Comment 2 Nick Clifton 2017-08-01 09:39:09 UTC
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.
Comment 3 Martin Schulze 2017-08-01 10:00:46 UTC
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
Comment 4 Nick Clifton 2017-08-01 11:29:53 UTC
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
Comment 5 Martin Schulze 2017-08-02 09:55:17 UTC
Sorry about the confusion, I see now that it was worded ambiguously.
I tried the patch and it works.
Comment 6 Sourceware Commits 2017-08-02 11:13:48 UTC
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.
Comment 7 Nick Clifton 2017-08-02 11:15:02 UTC
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
Comment 8 Martin Schulze 2017-08-02 11:16:56 UTC
I'll keep my eyes open. Thanks for the fast solution.
Comment 9 Pavel 2021-04-15 20:32:30 UTC
.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
Comment 10 Nick Clifton 2021-04-16 09:46:31 UTC
(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
Comment 11 Pavel 2021-04-16 12:49:46 UTC
(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
Comment 12 Pavel 2021-04-16 12:52:28 UTC
http://0x0.st/-Abf.o
http://0x0.st/-AbO.a
Comment 13 Nick Clifton 2021-04-16 14:58:11 UTC
(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
Comment 14 Pavel 2021-04-16 20:04:08 UTC
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
Comment 15 Nick Clifton 2021-04-19 13:12:31 UTC
Created attachment 13378 [details]
Proposed patch

Ah ha - I think that I have it.  Please could you try this uploaded patch ?
Comment 16 Pavel 2021-04-19 16:31:39 UTC
(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'.
Comment 17 Sourceware Commits 2021-04-19 16:39:55 UTC
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.
Comment 18 Nick Clifton 2021-04-19 16:45:26 UTC
It did take a bit of tracking down, but I am glad that I found it in the end.

Patch applied.