Bug 29042 - [2.38 regression] opcodes libtool regression (relinks libopcodes during install, picks up wrong libiberty from system)
Summary: [2.38 regression] opcodes libtool regression (relinks libopcodes during insta...
Status: NEW
Alias: None
Product: binutils
Classification: Unclassified
Component: binutils (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-04-10 21:13 UTC by Toolybird
Modified: 2023-04-03 05:43 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed: 2023-03-01 00:00:00


Attachments
log of failing libtool/linker command invocation (929 bytes, text/plain)
2022-04-13 20:37 UTC, Toolybird
Details
log with --verbose (3.75 KB, text/plain)
2022-04-13 20:37 UTC, Toolybird
Details
experimental patch (1.05 KB, patch)
2023-02-22 22:02 UTC, Andreas K. Huettel
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Toolybird 2022-04-10 21:13:36 UTC
2.38 release tarball
x86_64 Arch Linux

I'm seeing a regression upon `make install' in the opcodes dir. Essentially, the build fails because the wrong libiberty.a (in /usr/lib) is picked up instead of the one in the build tree. I only noticed this because my distro accidentally installed a non-PIC libiberty.a into /usr/lib. The weird thing is, the failure does not trigger every time. But it does fail every time when running `make install -j1'

This bug is very similar to:
https://sourceware.org/bugzilla/show_bug.cgi?id=27360

Again, the problem rears its ugly head because libtool is now forcing a relink upon `make install'. The relink is caused by this commit:

https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=2b677209

Reverting that commit makes the relink (and the failure) go away.

Adding -Wl,--verbose to LDFLAGS clearly shows /usr/lib/libiberty.a getting used in the relink.

To Reproduce:
1. Install a non-PIC libiberty.a into /usr/lib
2. Build binutils with `--enabled-shared' and `--prefix=/usr'
3. Install into a tmp DESTDIR by running something like:
   make -j1 prefix="$pkgdir/usr" tooldir="$pkgdir/usr" install
4. Watch it fail to install with the error:

/usr/bin/ld: /usr/lib/libiberty.a(regex.o): warning: relocation against `xre_max_failures' in read-only section `.text'
/usr/bin/ld: /usr/lib/libiberty.a(regex.o): relocation R_X86_64_PC32 against symbol `xre_max_failures' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: bad value
collect2: error: ld returned 1 exit status
libtool: install: error: relink `libopcodes.la' with the above command before installing it
make[4]: *** [Makefile:847: install-bfdlibLTLIBRARIES] Error 1
make[4]: Leaving directory '/build/binutils/src/binutils-build/opcodes'
make[3]: *** [Makefile:1260: install-am] Error 2
Comment 1 Toolybird 2022-04-13 04:18:13 UTC
After studying this for a bit, I'm fairly certain it can be fixed in the same way that libctf was fixed. i.e.

https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=7d53105d

For now, I'm just going to run with this dirty hack:

sed -i '/SHARED_LIBADD/s|../bfd/libbfd.la|-Wl,`pwd`/../bfd/.libs/libbfd.so|' \
  opcodes/configure

Thanks
Comment 2 Toolybird 2022-04-13 20:37:15 UTC
Created attachment 14062 [details]
log of failing libtool/linker command invocation
Comment 3 Toolybird 2022-04-13 20:37:54 UTC
Created attachment 14063 [details]
log with --verbose
Comment 4 Toolybird 2022-04-17 02:11:28 UTC
This bug is a little more serious than I first thought.

Even when /usr/lib/libiberty.a does not exist, the following combination of switches results in the wrong libiberty.a getting linked in:

--prefix=/usr
--enable-shared
--enable-install-libiberty

$ make -j2 prefix=/build/binutils/tmp/usr install

In the verbose log I see this:

attempt to open /build/binutils/tmp/usr/lib/libiberty.a succeeded

This means libopcodes is (re)linking against a non-pic libiberty. This is definitely wrong.

Problem goes away with `make -j1 ...install'. I noticed this while investigating issues of reproducibility.

A lot of build systems put "-j (n>1)" globally into MAKEFLAGS. What is the common wisdom here? Always `make install' binutils with -j1 ?

Thanks
Comment 5 Sam James 2023-02-09 01:41:48 UTC
I suspect this is the same as an issue we've been hitting in Gentoo (https://bugs.gentoo.org/834720) which is mostly noticeable if built the previous system copy of binutils with --enable-pgo=lto (or otherwise built binutils with LTO) with an older GCC, then rebuilding with a newer different version of GCC which marks itself as having a different bitcode version.

Manifests as (remains for newer versions):
```
lto1: fatal error: bytecode stream in file '/usr/lib64/binutils/x86_64-pc-linux-gnu/2.37_p1/libiberty.a' generated with LTO version 11.0 instead of the expected 11.2
compilation terminated.
lto-wrapper: fatal error: x86_64-pc-linux-gnu-gcc returned 1 exit status
compilation terminated.
```

I ended up hitting the same issue, just manifesting differently recently, when GCC's bitcode changed for 13.
Comment 6 Andreas K. Huettel 2023-02-22 22:02:26 UTC
Created attachment 14709 [details]
experimental patch

Please test this experimental patch. 

It tries to apply a similar hack as was previously done to libctf to libopcodes and libgprofng.
Comment 7 Maciej W. Rozycki 2023-03-01 12:11:24 UTC
(In reply to Toolybird from comment #4)
> Problem goes away with `make -j1 ...install'. I noticed this while
> investigating issues of reproducibility.
> 
> A lot of build systems put "-j (n>1)" globally into MAKEFLAGS. What is the
> common wisdom here? Always `make install' binutils with -j1 ?
This indicates we're missing a Makefile dependency for an `install'
target and a race occurs.

Also what are the contents of libbfd.la in the failed link?

NB I think having non-PIC libiberty.a installed system-wide with no
corresponding libiberty.so DSO is a system misconfiguration (but we're
supposed to cope anyway).