Bug 29435 - Building openblas with binutils 2.38 leads to "ELF load command address/offset not properly aligned"
Summary: Building openblas with binutils 2.38 leads to "ELF load command address/offse...
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: binutils (show other bugs)
Version: 2.38
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-08-01 17:00 UTC by Francois-Xavier Coudert
Modified: 2022-09-22 00:10 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments
A patch (444 bytes, patch)
2022-08-01 21:51 UTC, H.J. Lu
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Francois-Xavier Coudert 2022-08-01 17:00:28 UTC
This is an issue we originally saw during Homebrew CI on Linux: https://github.com/Homebrew/homebrew-core/pull/106978

We've narrowed it down to a binutils issues, and openblas maintainers seem to think the same: https://github.com/xianyi/OpenBLAS/issues/3708

Using the same setup, we see the build succeed and produce a working shared library with binutils 2.37, but produce an invalid library with binutils 2.38.

We configure openblas with DYNAMIC_ARCH=1 USE_OPENMP=1 NUM_THREADS=56 TARGET=CORE2
Compiling and linking a small test program against the library build with binutils 2.38 gives:

./test: error while loading shared libraries: libopenblas.so.0: ELF load command address/offset not properly aligned


The library is originally produced by this compilation command:

gcc -O2 -DSMALL_MATRIX_OPT -DMAX_STACK_ALLOC=2048 -fopenmp -Wall -m64 -DF_INTERFACE_GFORT -fPIC -DDYNAMIC_ARCH -DSMP_SERVER -DUSE_OPENMP -DNO_WARMUP -DMAX_CPU_NUMBER=56 -DMAX_PARALLEL_NUMBER=1 -DBUILD_SINGLE=1 -DBUILD_DOUBLE=1 -DBUILD_COMPLEX=1 -DBUILD_COMPLEX16=1 -DVERSION=\"0.3.20\" -UASMNAME -UASMFNAME -UNAME -UCNAME -UCHAR_NAME -UCHAR_CNAME -DASMNAME= -DASMFNAME=_ -DNAME=_ -DCNAME= -DCHAR_NAME=\"_\" -DCHAR_CNAME=\"\" -DNO_AFFINITY -I..  -shared -o ../libopenblasp-r0.3.20.so \
-Wl,--whole-archive ../libopenblasp-r0.3.20.a -Wl,--no-whole-archive \
-Wl,-soname,libopenblas.so.0 -lm -lpthread -lgfortran -lm -lpthread -lgfortran
Comment 1 Francois-Xavier Coudert 2022-08-01 19:27:57 UTC
How to reproduce:

1. Download and extract OpenBLAS-0.3.20 from https://github.com/xianyi/OpenBLAS/archive/v0.3.20.tar.gz

2. Run:
$ DYNAMIC_ARCH=1 TARGET=CORE2 make libs netlib shared

3. Create a test.c file:

$ cat test.c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "cblas.h"
                                                       
int main(void) {
  int i;
  double A[6] = {1.0, 2.0, 1.0, -3.0, 4.0, -1.0};
  double B[6] = {1.0, 2.0, 1.0, -3.0, 4.0, -1.0};
  double C[9] = {.5, .5, .5, .5, .5, .5, .5, .5, .5};
  cblas_dgemm(CblasColMajor, CblasNoTrans, CblasTrans,
              3, 3, 2, 1, A, 3, B, 3, 2, C, 3);
  for (i = 0; i < 9; i++)
    printf("%lf ", C[i]);
  printf("\\n");
  if (fabs(C[0]-11) > 1.e-5) abort();
  if (fabs(C[4]-21) > 1.e-5) abort();
  return 0;
}


4. Compile and run:

$ gcc test.c -I ./build2 -L ./build2 -lopenblas -pthread && ./a.out
./a.out: error while loading shared libraries: libopenblas.so.0: cannot open shared object file: No such file or directory


PS: If Openblas is built without DYNAMIC_ARCH=1, then the library produced works.
Comment 2 Francois-Xavier Coudert 2022-08-01 19:34:37 UTC
I have put a copy of the faulty library (built on x86_64 linux) as well as the same one (built without `DYNAMIC_ARCH`) at this URL if someone wants to debug this issue further: https://www.dropbox.com/s/yth3avnycvomv4d/binutils-debug.tar.gz?dl=0
Comment 3 H.J. Lu 2022-08-01 20:53:40 UTC
Please try binutils master branch. Which glibc are you using?
Comment 4 Francois-Xavier Coudert 2022-08-01 21:14:35 UTC
We've had this issue across a bunch of different systems. Mine has Debian GLIBC 2.31-13+deb11u3
Comment 5 H.J. Lu 2022-08-01 21:31:59 UTC
[hjl@gnu-tgl-3 pr29435]$ cat foo.c
__attribute__ ((aligned(0x8000)))
void
foo (void)
{
}
[hjl@gnu-tgl-3 pr29435]$ gcc -c foo.c
[hjl@gnu-tgl-3 pr29435]$ ld -shared -o libfoo.so foo.o
[hjl@gnu-tgl-3 pr29435]$ readelf -Wl libfoo.so 

Elf file type is DYN (Shared object file)
Entry point 0x0
There are 9 program headers, starting at offset 64

Program Headers:
  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
  LOAD           0x000000 0x0000000000000000 0x0000000000000000 0x0002ad 0x0002ad R   0x1000
  LOAD           0x008000 0x0000000000008000 0x0000000000008000 0x000007 0x000007 R E 0x8000
  LOAD           0x009000 0x0000000000009000 0x0000000000009000 0x000068 0x000068 R   0x8000
  LOAD           0x009f40 0x000000000000af40 0x000000000000af40 0x0000c0 0x0000c0 RW  0x8000
  DYNAMIC        0x009f40 0x000000000000af40 0x000000000000af40 0x0000c0 0x0000c0 RW  0x8
  NOTE           0x009000 0x0000000000009000 0x0000000000009000 0x000030 0x000030 R   0x8
  GNU_PROPERTY   0x009000 0x0000000000009000 0x0000000000009000 0x000030 0x000030 R   0x8
  GNU_STACK      0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW  0x10
  GNU_RELRO      0x009f40 0x000000000000af40 0x000000000000af40 0x0000c0 0x0000c0 R   0x1

 Section to Segment mapping:
  Segment Sections...
   00     .hash .gnu.hash .dynsym .dynstr 
   01     .text 
   02     .note.gnu.property .eh_frame 
   03     .dynamic 
   04     .dynamic 
   05     .note.gnu.property 
   06     .note.gnu.property 
   07     
   08     .dynamic 
[hjl@gnu-tgl-3 pr29435]$ 

Only the second PLT_LOAD segment should have 0x8000 alignment.
Comment 6 H.J. Lu 2022-08-01 21:51:35 UTC
Created attachment 14248 [details]
A patch

Try this.
Comment 7 Francois-Xavier Coudert 2022-08-02 08:27:31 UTC
It was reported by @carlocab at github (https://github.com/xianyi/OpenBLAS/issues/3708#issuecomment-1202146894) that the patch fixes the original issue.
Comment 8 cvs-commit@gcc.gnu.org 2022-08-03 20:41:55 UTC
The master branch has been updated by H.J. Lu <hjl@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=59f214544c50ec7ebbca285ff2b4949f48671690

commit 59f214544c50ec7ebbca285ff2b4949f48671690
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Mon Aug 1 16:02:39 2022 -0700

    elf: Reset alignment for each PT_LOAD segment
    
    Reset alignment for each PT_LOAD segment to avoid using alignment from
    the previous PT_LOAD segment.
    
    bfd/
    
            PR ld/29435
            * elf.c (assign_file_positions_for_load_sections): Reset
            alignment for each PT_LOAD segment.
    
    ld/
    
            PR ld/29435
            * testsuite/ld-elf/pr29435.d: New file.
            * testsuite/ld-elf/pr29435.s: Likewise.
Comment 9 cvs-commit@gcc.gnu.org 2022-09-22 00:08:40 UTC
The binutils-2_39-branch branch has been updated by Alan Modra <amodra@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=a98316d5cf970cbc99689797d84c2ea832bcdcbb

commit a98316d5cf970cbc99689797d84c2ea832bcdcbb
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Mon Aug 1 16:02:39 2022 -0700

    elf: Reset alignment for each PT_LOAD segment
    
    Reset alignment for each PT_LOAD segment to avoid using alignment from
    the previous PT_LOAD segment.
    
    bfd/
    
            PR ld/29435
            * elf.c (assign_file_positions_for_load_sections): Reset
            alignment for each PT_LOAD segment.
    
    ld/
    
            PR ld/29435
            * testsuite/ld-elf/pr29435.d: New file.
            * testsuite/ld-elf/pr29435.s: Likewise.
    
    (cherry picked from commit 59f214544c50ec7ebbca285ff2b4949f48671690)
Comment 10 cvs-commit@gcc.gnu.org 2022-09-22 00:09:25 UTC
The binutils-2_38-branch branch has been updated by Alan Modra <amodra@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=dc2474e7d204c124ab5a21b4490aa46eb7e1d4c3

commit dc2474e7d204c124ab5a21b4490aa46eb7e1d4c3
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Mon Aug 1 16:02:39 2022 -0700

    elf: Reset alignment for each PT_LOAD segment
    
    Reset alignment for each PT_LOAD segment to avoid using alignment from
    the previous PT_LOAD segment.
    
    bfd/
    
            PR ld/29435
            * elf.c (assign_file_positions_for_load_sections): Reset
            alignment for each PT_LOAD segment.
    
    ld/
    
            PR ld/29435
            * testsuite/ld-elf/pr29435.d: New file.
            * testsuite/ld-elf/pr29435.s: Likewise.
    
    (cherry picked from commit 59f214544c50ec7ebbca285ff2b4949f48671690)
Comment 11 Alan Modra 2022-09-22 00:10:22 UTC
Fixed everywhere