Skip to content

TST: exercise transitive RPATH lookup with a shared library chain - #905

Open
dnicolodi wants to merge 1 commit into
mesonbuild:mainfrom
dnicolodi:rpath-fixes-transitive
Open

dnicolodi wants to merge 1 commit into
mesonbuild:mainfrom
dnicolodi:rpath-fixes-transitive

Conversation

@dnicolodi

Copy link
Copy Markdown
Member

This includes #788 and adds a test to demonstrates the issue described here #788 (comment) I do not have a good idea about how to fix (but a couple of bad ones) and this use case does not seem to be common enough to hold merging #788 so I moved the addition of the test case here.

@rgommers

Copy link
Copy Markdown
Contributor

I do not have a good idea about how to fix (but a couple of bad ones) and this use case does not seem to be common enough to hold merging #788 so I moved the addition of the test case here.

Sounds fine to me. I can try to revisit, but yeah, it's not important enough to block a merge. If this affects a real-world package, we'll find out and fix it then with higher priority.

@rgommers

Copy link
Copy Markdown
Contributor

--force-rpath should fix this particular test case, however it looks like what is missing is a way to actually know what the type of the entry is. There's a couple of ways to get at that info:

  • Use readelf (new external tool dependency)
  • Use pyelftools (new Python dependency)
  • Reimplement the relevant part of header parsing, probably with the struct module - probably 20-40 lines of fairly low-level and ugly code.

I'd be most inclined to choose "reimplement", but I don't have any data to indicate this is urgent, so I'll park looking at this more for now.

@dnicolodi

Copy link
Copy Markdown
Member Author

Copying my previous comment over from #788 (comment) with minor edits.

This test package builds a chain extension module that links with a middle shared library, is installed in $platlib/chainhead/ and has install rpath set to $ORIGIN/lib and linker arguments forcing the use of DT_RPATH instead of DT_RUNPATH. The middle shared library links with a leaf shared library and is installed in $platlib/chainhead/lib/. The leaf shared library is also installed in $platlib/chainhead/lib/.

The use of DT_RPATH in the chain extension module should propagate the shared library search path along the chain, thus the middle shared library does not need to set an RPATH to find the leaf shared library.

This breaks because patchelf converts DT_RPATH entries into DT_RUNPATH entries and the latter do not propagate.

patchelf has a --force-rpath command line flag that forces the use of DT_RPATH instead of DT_RUNPATH https://manpages.debian.org/unstable/patchelf/patchelf.1.en.html#force-rpath. However, this is not what we need because converting DT_RUNPATH to DT_RPATH is not recommended either. We need a way to preserve the type of tag already present. I don't think there is a way to do this with current patchelf.

Relevant patchelf code:
https://github.com/NixOS/patchelf/blob/7688b17c18d16f67fa8d5a82a2404c2e3a18648d/src/patchelf.cc#L3124-L3137 and https://github.com/NixOS/patchelf/blob/7688b17c18d16f67fa8d5a82a2404c2e3a18648d/src/patchelf.cc#L1835-L1845

@dnicolodi

Copy link
Copy Markdown
Member Author

--force-rpath should fix this particular test case

It does, assuming that the binary uses DT_RPATH exclusively, and not a combination of DT_RPATH and DT_RUNPATH. I don't know if there is a linker incantation that would result in this.

however it looks like what is missing is a way to actually know what the type of the entry is. There's a couple of ways to get at that info:

* Use `readelf` (new external tool dependency)

readelf is part of binutils thus I think we can assume it is present if a compiler is present.

@rgommers

Copy link
Copy Markdown
Contributor

readelf is part of binutils thus I think we can assume it is present if a compiler is present.

Probably not fully robust. E.g., a container with only an LLVM toolchain may only have llvm-readelf, a conda-forge cross compilation setup may only have an executable like aarch64-conda-linux-gnu-readelf. It'll be much more rare that it's missing than patchelf, but we'd have to treat it similarly I think.

This branch has not been deployed

No deployments
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

Successfully merging this pull request may close these issues.

2 participants