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

Use DT_RUNPATH instead of DT_RPATH for -C rpath #30378

Closed
geofft opened this issue Dec 14, 2015 · 8 comments · Fixed by #30394
Closed

Use DT_RUNPATH instead of DT_RPATH for -C rpath #30378

geofft opened this issue Dec 14, 2015 · 8 comments · Fixed by #30394

Comments

@geofft
Copy link
Contributor

geofft commented Dec 14, 2015

On at least GNU/Linux, and possibly on other ELF-based systems, there are two types of rpath, one using the DT_RPATH entry in the dynamic headers and one using the DT_RUNPATH one. The distinction is that DT_RPATH takes precedence over the LD_LIBRARY_PATH environment variable, whereas DT_RUNPATH does not. The latter is more convenient and means that rpaths are less likely to get in your way, since you can override them. DT_RPATH is also claimed to be deprecated by the ld.so manpage. So I think that rustc -C rpath should generate DT_RUNPATH where available.

glibc has supported this since at least 1999. musl 1.1.6 (January 2015) seems to honor DT_RUNPATH but not treat it differently. You can emit both, and the GNU dynamic linker ignores DT_RPATH.

You can tell GNU ld to emit DT_RUNPATH instead of DT_RPATH by adding --enable-new-dtags, probably something like

diff --git a/src/librustc_back/rpath.rs b/src/librustc_back/rpath.rs
index 6674d31..e96f33d 100644
--- a/src/librustc_back/rpath.rs
+++ b/src/librustc_back/rpath.rs
@@ -41,6 +41,7 @@ pub fn get_rpath_flags(config: &mut RPathConfig) -> Vec<String> {

 fn rpaths_to_flags(rpaths: &[String]) -> Vec<String> {
     let mut ret = Vec::new();
+    ret.push("-Wl,--enable-new-dtags".to_string());
     for rpath in rpaths {
         ret.push(format!("-Wl,-rpath,{}", &(*rpath)));
     }

However, neither Apple's linker nor lld supports this, and I'm not really sure how to make this platform-conditional. Hence a bug instead of a PR.

@jethrogb
Copy link
Contributor

This should probably be encoded somewhere in the Target config.

@geofft
Copy link
Contributor Author

geofft commented Dec 15, 2015

Oh hey, there's a linker_is_gnu. I'll post a PR if my local build works.

@geofft
Copy link
Contributor Author

geofft commented Dec 15, 2015

Seems to work on GNU/Linux, PR opened. My local build with ./configure --enable-rpath is still able to run directly out of x86_64-unknown-linux-gnu/stage2/bin/rustc, and the binary has DT_RUNPATH according to readelf -d.

I haven't tested with musl or non-Linux.

One thing worth noting for the record is that DT_RUNPATH is only used for direct dependencies; it does not apply to indirect/recursive dependencies the way that DT_RPATH and LD_LIBRARY_PATH do. This is undocumented but mentioned in random blog posts and mailing list threads. I think this is fine and arguably correct, since this is just about Rust binaries and libraries being able to find their own dependencies. You should tell your native library build process to also set rpaths, or you should set LD_LIBRARY_PATH. But maybe I'm missing a use case.

geofft added a commit to geofft/rust that referenced this issue Dec 16, 2015
This causes the linker to emit DT_RUNPATH instead of DT_RPATH, which
fixes rust-lang#30378.
bors added a commit that referenced this issue Dec 19, 2015
This causes the linker to emit DT_RUNPATH instead of DT_RPATH, which fixes #30378. See that bug for rationale.
jroesch pushed a commit to jroesch/rust that referenced this issue Jan 4, 2016
This causes the linker to emit DT_RUNPATH instead of DT_RPATH, which
fixes rust-lang#30378.
cardoe added a commit to starlab-io/meta-rust that referenced this issue Apr 6, 2016
--enable-new-dtags is the default since Rust 1.7.0 due to
rust-lang/rust#30378.

Signed-off-by: Doug Goldstein <cardoe@cardoe.com>
cardoe added a commit to starlab-io/meta-rust that referenced this issue Apr 6, 2016
--enable-new-dtags is the default since Rust 1.7.0 due to
rust-lang/rust#30378.

Signed-off-by: Doug Goldstein <cardoe@cardoe.com>
cardoe added a commit to starlab-io/meta-rust that referenced this issue Apr 11, 2016
--enable-new-dtags is the default since Rust 1.7.0 due to
rust-lang/rust#30378.

Signed-off-by: Doug Goldstein <cardoe@cardoe.com>
@MartinHusemann
Copy link
Contributor

DT_RUNPATH is a Linuxism. Using it whenver config.linker_is_gnu is not correct.

@jethrogb
Copy link
Contributor

@MartinHusemann a two year old closed ticket is not the correct place to discuss this. Additionally, I can't find any evidence in the glibc source that DT_RUNPATH is specific to Linux. If you have a problem related to this, can you open a new issue with

  1. the platform you're using
  2. why your platform is using GNU ld but not GNU rtld?

@geofft
Copy link
Contributor Author

geofft commented Nov 23, 2017

@MartinHusemann which specific OS (kernel + libc combination) are you noticing DT_RUNPATH absent on?

I guess the thing I really want is that the dynamic linker is GNU libc, not that the compile-time linker is GNU ld. But as far as I know, non-Linux kernels + GNU libc (e.g., Hurd, GNU/kFreeBSD) support DT_RUNPATH. And I think that passing --enable-new-dtags to GNU ld targeting a platform which doesn't support it does nothing, though it's been a while since I've tried.

... However, musl and bionic both seem to support DT_RUNPATH. So given that Rust doesn't support the Hurd yet and GNU/kFreeBSD is basically dead, maybe it's better in practice to look for a Linux kernel, even though DT_RUNPATH isn't a kernel feature.

@MartinHusemann
Copy link
Contributor

Sorry, I missed the (prominent) "Closed" sign at the top. I did open a new ticket already, see #46204, let's keep further discussions there.

@richfelker
Copy link

Old issue, but for the record: musl treats DT_RPATH and DT_RUNPATH identically. Either is searched after LD_LIBRARY_PATH, and affects both direct and indirect dependency loading. So it doesn't matter which you use for musl targets.

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 a pull request may close this issue.

4 participants