Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Version-script difference between mold and ld #287

Closed
LazyDodo opened this issue Jan 20, 2022 · 5 comments
Closed

Version-script difference between mold and ld #287

LazyDodo opened this issue Jan 20, 2022 · 5 comments

Comments

@LazyDodo
Copy link

Found while validating the fix for #277 and comparing the symbols of blender linked with both ld and mold, I'll be honest, I don't know the specs well enough to being able to tell who is "wrong" or "right" here however....

a symbol that matches both global and local in a version script, ld keeps a symbol mold excludes.

given the following version script

{
global:
  *;
  *_boost*;
local:
  *boost*;
};

and the following 2 symbols GlowSequence_boost_factor_get , _ZN5boost11this_thread18interruption_pointEv

ld will export GlowSequence_boost_factor_get while mold hides both symbols.

repro case attached below

version_test_global_local.tar.gz

output

root@SRV:/mnt/e/mold_test2# mkdir build
root@SRV:/mnt/e/mold_test2# cd build
root@SRV:/mnt/e/mold_test2/build# cmake ..
-- The C compiler identification is GNU 9.3.0
-- The CXX compiler identification is GNU 9.3.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /mnt/e/mold_test2/build
root@SRV:/mnt/e/mold_test2/build# make
Scanning dependencies of target libA
[ 25%] Building C object CMakeFiles/libA.dir/a.c.o
[ 50%] Linking C static library liblibA.a
[ 50%] Built target libA
Scanning dependencies of target version_test
[ 75%] Building C object CMakeFiles/version_test.dir/vtest.c.o
[100%] Linking C shared library libversion_test.so
[100%] Built target version_test
root@SRV:/mnt/e/mold_test2/build# readelf --dyn-syms ./libversion_test.so

Symbol table '.dynsym' contains 8 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_deregisterTMCloneTab
     2: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND puts@GLIBC_2.2.5 (2)
     3: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
     4: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_registerTMCloneTable
     5: 0000000000000000     0 FUNC    WEAK   DEFAULT  UND __cxa_finalize@GLIBC_2.2.5 (2)
     6: 000000000000114e    23 FUNC    GLOBAL DEFAULT   14 GlowSequence_boost_factor
     7: 0000000000001139    21 FUNC    GLOBAL DEFAULT   14 vtest

root@SRV:/mnt/e/mold_test2/build# cmake -DUSE_MOLD=On .
-- Configuring done
-- Generating done
-- Build files have been written to: /mnt/e/mold_test2/build
root@SRV:/mnt/e/mold_test2/build# make
Scanning dependencies of target libA
[ 25%] Building C object CMakeFiles/libA.dir/a.c.o
[ 50%] Linking C static library liblibA.a
[ 50%] Built target libA
Scanning dependencies of target version_test
[ 75%] Building C object CMakeFiles/version_test.dir/vtest.c.o
[100%] Linking C shared library libversion_test.so
[100%] Built target version_test
root@SRV:/mnt/e/mold_test2/build# readelf --dyn-syms ./libversion_test.so

Symbol table '.dynsym' contains 7 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
     2: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_deregisterTMCloneTab
     3: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_registerTMCloneTable
     4: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND puts@GLIBC_2.2.5 (2)
     5: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __cxa_finalize@GLIBC_2.2.5 (2)
     6: 0000000000001119    21 FUNC    GLOBAL DEFAULT   17 vtest
@rui314
Copy link
Owner

rui314 commented Jan 20, 2022

This is a difficult case. As you can imagine, mold applies version script rules from top to bottom, so all symbols that match *_boost* become global and then some of them become local by the following *boost*.

GNU ld might be resolving this ambiguity by not overwriting a symbol version once a symbol name matches some pattern. But if that's the case, all symbols would be exported because they match * at the beginning of the file. But again, * might be handled as a special case by GNU ld.

Version script's grammar is actually odd compared to its purpose. In addition to that, use of a version script usually slows down a linker a lot, as a linker has to do lots of glob pattern matching.

Let me take a look in more closely. I have an idea to rewrite version script application code, and that might be able to solve the issue and the performance issue as well.

@LazyDodo
Copy link
Author

Like I said, I'm not knowledgeable enough to pick a team here on who is wrong or right, it was a difference nonetheless I thought was worth pointing out. It's currently not causing any issues for us, if you want to close this as won't-fix that be perfectly acceptable to me.

@rui314
Copy link
Owner

rui314 commented Jan 20, 2022

As I said in the last comment, I'll try to rewrite mold's version script processing code to see if it can resolve this compatibility issue, so I'll keep this bug open. I'll update this bug when I make progress.

@rui314 rui314 closed this as completed in d0c1c4d Jan 21, 2022
@rui314
Copy link
Owner

rui314 commented Jan 21, 2022

I think I fixed the issue in the above commit. Please verify when you have time. Thanks!

@LazyDodo
Copy link
Author

Seems to have done the trick! we're down to a single symbol difference between ld and mold, I'll have to find some time to extract a repro case for you next week.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants