Bug 2101570 - gcc on RHEL7 does not produce usable binaries using target and target_clone syntax
Summary: gcc on RHEL7 does not produce usable binaries using target and target_clone s...
Keywords:
Status: CLOSED WONTFIX
Alias: None
Product: Red Hat Developer Toolset
Classification: Red Hat
Component: gcc
Version: DTS 11.1 RHEL 7
Hardware: x86_64
OS: Linux
medium
medium
Target Milestone: alpha
: 9.1
Assignee: Marek Polacek
QA Contact: Václav Kadlčík
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2022-06-27 20:40 UTC by Andrew Mike
Modified: 2023-07-18 14:10 UTC (History)
10 users (show)

Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2022-07-18 14:21:42 UTC
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)
Test package for issue (1.19 KB, application/gzip)
2022-06-27 20:40 UTC, Andrew Mike
no flags Details


Links
System ID Private Priority Status Summary Last Updated
Red Hat Issue Tracker DTS-412 0 None None None 2022-06-27 20:42:34 UTC

Description Andrew Mike 2022-06-27 20:40:20 UTC
Created attachment 1893034 [details]
Test package for issue

Description of problem: When using devtoolset-10 on RHEL 7, gcc does not produce usable binaries using target and target_clone syntax.

Version-Release number of selected component (if applicable):
devtoolset-11-11.1-2.el7

How reproducible: 100%


Steps to Reproduce:
1. Unzip test zip file into directory.
2. Run "make".
3. Run "LD_LIBRARY_PATH=." ./test_dlopen

Actual results:
Program crashes with segmentation fault.

Expected results:
Program works.

Additional info:
- This also fails on devtoolset-9 and -10, but only on RHEL 7; RHEL 8 appears unaffected.

Comment 2 Marek Polacek 2022-07-14 22:11:16 UTC
I don't think this is about what code gcc generates: the same code is emitted with GCC 11
on both RHEL 7 and 8.  In fact, the binary built on RHEL8 crashes on RHEL7, and the binary
built on RHEL7 works on RHEL8.

# LD_LIBRARY_PATH=. gdb -q --args /lib64/ld-linux-x86-64.so.2 ./test_dlopen
Reading symbols from /lib64/ld-linux-x86-64.so.2...
Reading symbols from /usr/lib/debug/usr/lib64/ld-2.17.so.debug...
(gdb) r
Starting program: /usr/lib64/ld-linux-x86-64.so.2 ./test_dlopen
Opening libirisdb.so

Program received signal SIGSEGV, Segmentation fault.
0x00000000000010a6 in ?? ()
(gdb) bt
#0  0x00000000000010a6 in ?? ()
#1  0x00007ffff7ff4364 in ?? ()
#2  0x00007fffffffd920 in ?? ()
#3  0x00007ffff7de76c8 in elf_machine_rela (reloc=0x7ffff7ff38f8, reloc=0x7ffff7ff38f8, 
    skip_ifunc=<optimized out>, reloc_addr_arg=0x7ffff7ff7038, version=<optimized out>, sym=0x7ffff7ff34d8, 
    map=0x7ffff7fff030) at ../sysdeps/x86_64/dl-machine.h:308
#4  elf_dynamic_do_Rela (skip_ifunc=<optimized out>, lazy=<optimized out>, nrelative=<optimized out>, 
    relsize=<optimized out>, reladdr=<optimized out>, map=0x7ffff7fff030) at do-rel.h:137
#5  _dl_relocate_object (scope=<optimized out>, reloc_mode=<optimized out>, 
    consider_profiling=<optimized out>) at dl-reloc.c:259
Backtrace stopped: frame did not save the PC

Comment 3 Marek Polacek 2022-07-14 22:54:29 UTC
tail of LD_DEBUG=all output just before the crash:

     33847:	symbol=_ZNSt8ios_base4InitC1Ev;  lookup in file=/lib64/ld-linux-x86-64.so.2 [0]
     33847:	symbol=_ZNSt8ios_base4InitC1Ev;  lookup in file=./libirisdb.so [0]
     33847:	symbol=_ZNSt8ios_base4InitC1Ev;  lookup in file=/lib64/libstdc++.so.6 [0]
     33847:	binding file ./libirisdb.so [0] to /lib64/libstdc++.so.6 [0]: normal symbol `_ZNSt8ios_base4InitC1Ev' [GLIBCXX_3.4]
     33847:	symbol=_Z18optimized_functionIiiEiT_T0_;  lookup in file=./test_dlopen [0]
     33847:	symbol=_Z18optimized_functionIiiEiT_T0_;  lookup in file=/lib64/libdl.so.2 [0]
     33847:	symbol=_Z18optimized_functionIiiEiT_T0_;  lookup in file=/lib64/libc.so.6 [0]
     33847:	symbol=_Z18optimized_functionIiiEiT_T0_;  lookup in file=/lib64/ld-linux-x86-64.so.2 [0]
     33847:	symbol=_Z18optimized_functionIiiEiT_T0_;  lookup in file=./libirisdb.so [0]
     33847:	binding file ./libirisdb.so [0] to ./libirisdb.so [0]: normal symbol `_Z18optimized_functionIiiEiT_T0_'

Comment 4 Marek Polacek 2022-07-14 23:04:58 UTC
Reduced.  If I remove the target_clones, it works.

# gcc test_dlopen.c -o test_dlopen -ldl; g++ -fpic -c l.cc; g++ -shared -o libirisdb.so l.o; LD_LIBRARY_PATH=. ./test_dlopen
Opening libirisdb.so
Segmentation fault

# cat test_dlopen.c
#include <stdio.h>
#include <dlfcn.h>

#define LIBRARY_NAME "libirisdb.so"

int main() {
    // open the library
  printf("Opening %s\n",LIBRARY_NAME);
  void* handle = dlopen(LIBRARY_NAME, RTLD_NOW);
    
  if (!handle) {
    printf("open failed %s\n",dlerror());
    return 1;
  }
  
  // close the library
  printf("closing \n");
  dlclose(handle);
  return(0);
}

# cat l.cc
template <typename vector_T, typename elem_T>
__attribute__((target_clones("avx2", "default")))
int optimized_function(vector_T, elem_T)
{
  return 1;
}

int mv_cppfunction(int input)
{
  return optimized_function<int,int>(input,input); 
}

Comment 5 Marek Polacek 2022-07-15 22:24:14 UTC
This is a libgcc problem.  We are calling __cpu_indicator_init, an external function from libgcc.so,
while processing an IFUNC in a dlopen, and that function needs a run-time relocation, but at this
point the relocation hasn't been set up yet.

This work on RHEL8 because the system gcc has this patch:
https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=abd0cdc9c07c92d6cab15afc4fd38945d536751b
However, backporting the patch to RHEL7 at this stage is not feasible.

There are 2 workarounds:

1) Link with -lgcc while creating libirisdb.so.  Then libgcc.a (specifically, cpuinfo.o) will
get pulled in while linking therefore avoiding the need to resolve the function at runtime.
2) Don't use the target_clones attribute.  Obviously, the specialized avx2 functions will
not be used then.


Special thanks to Florian W. who found the root issue and the patch.

Comment 6 Marek Polacek 2022-07-18 14:21:42 UTC
Closing as I don't plan to change neither DTS gcc nor system RHEL7 libgcc.


Note You need to log in before you can comment on or make changes to this bug.