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

Allow more modifications of .gnu.version_r #369

Open
martinetd opened this issue Mar 18, 2022 · 1 comment
Open

Allow more modifications of .gnu.version_r #369

martinetd opened this issue Mar 18, 2022 · 1 comment

Comments

@martinetd
Copy link
Member

martinetd commented Mar 18, 2022

This is sort of a follow-up on #84 which added support for .gnu.version_r in --replace-needed.

Is your feature request related to a problem? Please describe.

My usecase for this is a binary lib I absolutely cannot replace that was compiled for a glibc too recent for the system I need to run it on.
It ends up with something like this:

$ objdump -x badlib
...
Version References:
  required from ld-linux-aarch64.so.1:
    0x06969197 0x00 03 GLIBC_2.17
  required from libc.so.6:
    0x069691b3 0x00 04 GLIBC_2.33
    0x06969197 0x00 02 GLIBC_2.17
...
$ nm -D libgbm.so | grep 2.33
                 U fstat@GLIBC_2.33

on a system with glibc 2.32, so without that fstat, so it obviously won't run.

Describe the solution you'd like

The best possible thing I can think of would be to have a partial replace-needed, so I could keep libc for whatever it finds useful in GLIBC_2.17 and replace GLIBC_2.33 with another lib.
That would keep a versioned symbol for fstat (no risk of confusion) with a minimal change.

Something I thought would be simpler is to have --clear-symbol-version remove the version in .gnu.version_r if there are no other symbol with that version -- I've looked a bit at the code and it's probably possible, although would be messy e.g.

  • in clearSymbolVersions remember all distinct versyms[i] we've seen just before clearing it
  • for all of these check if they have other users, if not remember them for cleanup
  • if there is any to cleanup reproduce what is done in replaceNeeded and skip list element, truncate list early or remove lib completely as appropriate. This last part would probably be annoying to get right all the time...

Describe alternatives you've considered
I've tried a few things:

  • I've tried replace-needed as is, replacing libc.so.6 with a wrapper lib, but things just segfault accessing symbols defined in the wrapper... I'm probably missing something obvious there.
  • I've managed to work around it manually by handcrafting the .gnu.version_r in a hex editor so it no longer requires GLIBC_2.33 there, patchelf --clear-symbol-version fstat to remove the binding to fstat, and patchelf --add-needed libc_2.33_compat.so to provide the fstat symbol definition without a version.
    This actually works, but I'd rather no have a "get a human to modify some hex string" everytime we need to upgrade it.

Additional context
Happy to try any other solution if you have other ideas -- I'm throwing this here but I likely won't have time to implement anything before a few weeks, and it's just as possible we stay with my temporary solution saying it's not getting updated often anyway, but if there's a proper way of doing this I'm all ears.
The real ideal solution would be to get them to provide sources or at least a build for the platform I'm targeting, but that's quite unlikely to happen...

Thanks!

@sulix
Copy link

sulix commented Apr 12, 2022

Something I thought would be simpler is to have --clear-symbol-version remove the version in .gnu.version_r if there are no other symbol with that version -- I've looked a bit at the code and it's probably possible, although would be messy e.g.

* in clearSymbolVersions remember all distinct versyms[i] we've seen just before clearing it

* for all of these check if they have other users, if not remember them for cleanup

* if there is any to cleanup reproduce what is done in replaceNeeded and skip list element, truncate list early or remove lib completely as appropriate. This last part would probably be annoying to get right all the time...

FYI: I found I needed the same thing (removing unused version entries) and have implemented it in #374. The implementation isn't perfect (it doesn't rebuild the entire section, it just unlinks the Elf_Vernaux elements), but it works well enough for me.

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