Updating binutils to 2.35 broke libQt5Core5.so.5, QCoreApplication::self didn't work anymore (https://bugzilla.suse.com/show_bug.cgi?id=1175278#c9). It's caused by "ld: Handle --dynamic-list* before -Bsymbolic -Bsymbolic-functions", which effectively means that -Bsymbolic-functions is ignored if --dynamic-list is given, so the issue can be replicated on 2.34 as well. break.i: void setValue(int v); extern int value; int main() { setValue(42); return value; } lib.i: int value = 0; void setValue(int v) { value = v; } lib.dynlist: { extern "C" { "setValue"; }; }; With -Bsymbolic-functions, it works as expected: > gcc -fPIC -shared -Wl,-Bsymbolic-functions -Wl,--dynamic-list,lib.dynlist -o lib.so lib.i && readelf --dyn-syms -r lib.so | grep value 000000003fe8 000600000006 R_X86_64_GLOB_DAT 0000000000004024 value + 0 6: 0000000000004024 4 OBJECT GLOBAL DEFAULT 22 value > gcc -Wl,--no-undefined lib.so break.i -o break && LD_LIBRARY_PATH=$PWD ./break; echo $? 42 Without, the relocation is missing and setValue writes into a different value than main reads from: > gcc -fPIC -shared -Wl,--dynamic-list,lib.dynlist -o lib.so lib.i && readelf --dyn-syms -r lib.so | grep value 6: 0000000000004024 4 OBJECT GLOBAL DEFAULT 22 value > gcc -Wl,--no-undefined lib.so break.i -o break && LD_LIBRARY_PATH=$PWD ./break; echo $? 0 If "value" is mentioned in lib.dynlist or --dynamic-list-data is used it works, so it seems like objects have to be mentioned in lib.dynlist as well. But then the symbol should be missing entirely and linking fail, instead of just the missing relocation resulting in runtime issues, right?
Please make it a run-time test.
(In reply to H.J. Lu from comment #1) > Please make it a run-time test. Sorry, I don't understand what you mean by that. The break executable only returns 42 with the working lib.so, it doesn't have to be recompiled. FTR, this issue does not happen with gold: # gcc -fuse-ld=gold -fPIC -shared -Wl,--dynamic-list,lib.dynlist -o lib.so lib.i && readelf --dyn-syms -r lib.so | grep value 000000001fe0 000800000006 R_X86_64_GLOB_DAT 0000000000002014 value + 0 8: 0000000000002014 4 OBJECT GLOBAL DEFAULT 24 value # LD_LIBRARY_PATH=$PWD ./break; echo $? 42
(In reply to H.J. Lu from comment #1) > Please make it a run-time test. It is a run-time test-case. He executes binary called 'break'.
'--dynamic-list=DYNAMIC-LIST-FILE' Specify the name of a dynamic list file to the linker. This is typically used when creating shared libraries to specify a list of global symbols whose references shouldn't be bound to the definition within the shared library, or creating dynamically linked executables to specify a list of symbols which should be added to the symbol table in the executable. This option is only meaningful on ELF platforms which support shared libraries. So symbols aren't on the dynamic list will be bound to the definition within the shared library. The linker behavior matches the linker manual.
It sounds like you need '--dynamic-list-data' Include all global data symbols to the dynamic list.
(In reply to H.J. Lu from comment #4) > '--dynamic-list=DYNAMIC-LIST-FILE' > Specify the name of a dynamic list file to the linker. This is > typically used when creating shared libraries to specify a list of > global symbols whose references shouldn't be bound to the > definition within the shared library, or creating dynamically > linked executables to specify a list of symbols which should be > added to the symbol table in the executable. This option is only > meaningful on ELF platforms which support shared libraries. > > So symbols aren't on the dynamic list will be bound to the definition > within the shared library. The linker behavior matches the linker > manual. That doesn't explain the behaviour change with -Bsymbolic-functions and the different behaviour with gold. The definition of the symbol is inside lib.so, so there is no reason this shouldn't work. This breaks because the break binary has a R_X86_64_COPY relocation, which essentially moves the symbol out of the lib into the executable. IMO copy relocations are an implementation detail which should be made as compatible as possible, in this case maybe by making --dynamic-list-data the default if --dynamic-list is passed.
(In reply to Fabian Vogt from comment #6) > (In reply to H.J. Lu from comment #4) > > '--dynamic-list=DYNAMIC-LIST-FILE' > > Specify the name of a dynamic list file to the linker. This is > > typically used when creating shared libraries to specify a list of > > global symbols whose references shouldn't be bound to the > > definition within the shared library, or creating dynamically > > linked executables to specify a list of symbols which should be > > added to the symbol table in the executable. This option is only > > meaningful on ELF platforms which support shared libraries. > > > > So symbols aren't on the dynamic list will be bound to the definition > > within the shared library. The linker behavior matches the linker > > manual. > > That doesn't explain the behaviour change with -Bsymbolic-functions and the > different behaviour with gold. Let focus on ld. -Bsymbolic-functions changes behavior is a bug, which has been fixed in 2.35. > The definition of the symbol is inside lib.so, so there is no reason this > shouldn't work. ? > This breaks because the break binary has a R_X86_64_COPY relocation, which > essentially moves the symbol out of the lib into the executable. > > IMO copy relocations are an implementation detail which should be made as > compatible as possible, in this case maybe by making --dynamic-list-data the > default if --dynamic-list is passed. There is no different between value and setValue as far as --dynamic-list is concerned. Linker provides precise controls with command-line options. You need to tell linker exactly what you need.
I wonder if we shouldn't mark symbols that are internalized but referenced (and hence have relocs to them removed) and still exported such that when a binary is created that contains a copy relocation to them could at least be warned about when creating such binary. There are a couple bits available in the symbol table entries.
(In reply to Michael Matz from comment #8) > I wonder if we shouldn't mark symbols that are internalized but referenced > (and hence have relocs to them removed) and still exported such that when a > binary is created that contains a copy relocation to them could at least be > warned about > when creating such binary. There are a couple bits available in the symbol > table > entries. Also see: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19520
*** Bug 26928 has been marked as a duplicate of this bug. ***