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

relocation-model=dynamic-no-pic passes -pie to ld #35061

Closed
jvns opened this issue Jul 27, 2016 · 9 comments · Fixed by #48076
Closed

relocation-model=dynamic-no-pic passes -pie to ld #35061

jvns opened this issue Jul 27, 2016 · 9 comments · Fixed by #48076
Labels
A-frontend Area: frontend (errors, parsing and HIR) C-bug Category: This is a bug.

Comments

@jvns
Copy link
Contributor

jvns commented Jul 27, 2016

I'm having trouble linking a Rust program to a non-position-independent C library. When I manually remove the -pie flag from the ld step that rustc runs, everything works correctly. I think that -C relocation-model=dynamic-no-pic should remove the -pie flag for me, but it doesn't.

Here's what I think is going on:

When I run

strace -s 300 -e execve -f rustup run nightly rustc hello.rs -v -C relocation-model=dynamic-no-pic

It runs ld with the -pie flag:

execve("/usr/bin/ld", ["/usr/bin/ld", "-pie"

But when I read the rustc code here, it seems like the intention is that -pie should only be passed to ld when relocation-model=pic. That is, if we're not compiling a position independent executable, then we should not pass the position independent executable -pie flag to ld.

I think what may be happening here is that somehow the defaults from

relocation_model: "pic".to_string(),
are overriding the command line options I'm setting.

This happens with stable and also the nightly I tried:

rustc 1.12.0-nightly (9316ae515 2016-07-24)
binary: rustc
commit-hash: 9316ae515e2f8f3f497fb4f1559910c1eef2433d
commit-date: 2016-07-24
host: x86_64-unknown-linux-gnu
release: 1.12.0-nightly
@nagisa
Copy link
Member

nagisa commented Jul 27, 2016

-pie and -pic are two distinct things. -pie is also unrelated to the relocation-model option. Interestingly, I do not remember us having an option to disable PIE; we should have one.

@steveklabnik steveklabnik added the A-frontend Area: frontend (errors, parsing and HIR) label Jul 27, 2016
@kamalmarhubi
Copy link
Contributor

I did a bit of reading and here's what I figured out, please correct me if any of this is wrong. Linkers are new to me!

Rust builds position independent executables by default on platforms that support it. These platforms have a relocation model of pic in their target config. The code @jvns linked is what sets that linker option, except if it's disallowed by -static.

The correct solution to this is to add a -C no-pie codegen flag, or something like that. Does this sound right?

@riomus
Copy link

riomus commented Nov 16, 2016

Hi,

I am having the same issue. I am trying to link against non-position-independent C library, build process ends without error but results returned by Rust bindings are different (and incorrect) than those returned from clean C implementation.

In order to overcome that issue currently I am setting RUSTFLAGS="-C relocation-model=dynamic-no-pic -C linker=./linker" where linker is bash script that wraps cc and filter -pie flags:

 #!/bin/bash 

filtered_args=""

for arg; do

    if [ "$arg" != "-pie" ]
    then
        filtered_args="$filtered_args $arg"

    fi

done

command="cc $filtered_args"

echo " $command" > /tmp/linker

eval "$command"

@jsgf
Copy link
Contributor

jsgf commented Jan 2, 2017

I'm also having this problem. I assumed that passing -C relocation-model=static when doing a --crate-type=bin build would suppress -pie on the linker command line.

(cc: @alexcrichton)

bors added a commit that referenced this issue Mar 4, 2017
Let `-Crelocation-model` better control `-pie` linking

Prior to this, if relocation model in the target options was "pic", as
most targets have it, then the user's `-Crelocation-model` had no effect
on whether `-pie` would be used.  Only `-Clink-arg=-static` would have a
further override here.

Now we use `context::get_reloc_model`, which gives precedence to the
user's option, and if it's `RelocMode::PIC` we enable `-pie`.  This is
the same test as `context::is_pie_binary`, except that folds across all
`sess.crate_types`, not just the current one.

Fixes #35061.
@nstoddard
Copy link

I'm still seeing this issue. Not sure if it's a regression or I'm doing something wrong. I have a "hello world" program in main.rs, and when I run strace -s 300 -e execve -f rustc main.rs -C relocation-model=dynamic-no-pic, the resulting call to ld includes -pie.

I'm using nightly rust on Ubuntu: rustc 1.19.0-nightly (386b0b9d3 2017-05-14).

@yodaldevoid
Copy link
Contributor

yodaldevoid commented Jul 23, 2017

I'm using nightly rust on Ubuntu

So, the problem here isn't with rust, but with the linker. In Ubuntu 15.10 and later the default GCC toolchain installed has been compiled with --enable-default-pie which causes -fPIE and -fpie to be passed to cc during code generation and -pie to ld during linking. Now, the linking part is what is important here as rust on most platforms uses cc as the linker for most targets. So, though no PIC or PIE code may have been generated by rustc, the linker will still try to link as with PIE in mind, breaking when trying to compile with -static and the like. To work around this rustc will need to see that the linker has been compiled with PIE as the default and pass -no-pie to the linker if using GCC or something similar for other linkers. Code to do this can be seen in this PR for Tarpaulin though it is only meant for Linux in that state and can be improved greatly if in tree.

EDIT: Don't know why Github isn't linking cross-project PRs correctly right now.

@Mark-Simulacrum Mark-Simulacrum added the C-bug Category: This is a bug. label Jul 25, 2017
@Others
Copy link
Contributor

Others commented Jul 26, 2017

Can this issue be resolved by always passing -no-pie, except when compiling with pic?

@yodaldevoid
Copy link
Contributor

Can this issue be resolved by always passing -no-pie, except when compiling with pic?

Sadly, no. In testing I have seen that any build of GCC that was not built with --enable-default-pie rejects the option and fails to run. This is why in the PR that I linked the linker was queried to see if it was compiled with --enable-default-pie before tacking on -no-pie.

@xd009642
Copy link
Contributor

xd009642 commented Aug 8, 2017

So it's came out from the discussion on an issue related to this in tarpaulin that passing -no-pie before -shared (and maybe then -static if it exists for static linkages as well) resolves the issue. I'm going to test this tarpaulin side and I can report back but I feel it would be best if this could be solved rustc side as it can affect any user in a similar situation.

canarysnort01 added a commit to canarysnort01/rust that referenced this issue Feb 14, 2018
When linking with gcc, run gcc -v to see if --enable-default-pie is
compiled in. If it is, pass -no-pie when necessary to disable pie.
Otherwise, pass -pie when necessary to enable it.

Fixes rust-lang#48032 and fixes rust-lang#35061
kennytm added a commit to kennytm/rust that referenced this issue Feb 25, 2018
pass correct pie args to gcc linker

When linking with gcc, run gcc -v to see if --enable-default-pie is
compiled in. If it is, pass -no-pie when necessary to disable pie.
Otherwise, pass -pie when necessary to enable it.

Fixes rust-lang#48032 and fixes rust-lang#35061
kulp added a commit to kulp/lightning-sys that referenced this issue May 9, 2020
It appears from rust-lang/rust#35061 and from [some build failures][1]
that position-independent executables are being built (see "-pie" flag
in [1]'s build output), which would require the objects in
`liblightning.a` to be built with `-fPIC` on x86_64, which is not
desirable.

Static linking would be more desirable in the long term, since it could
enable extra optimizations (`-flto` particularly) and generate better
code, but for now, switch to dynamic linking until a portable way
becomes available to ensure linking succeeds statically.

[1]: https://travis-ci.org/github/kulp/lightning-sys/jobs/685111507
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-frontend Area: frontend (errors, parsing and HIR) C-bug Category: This is a bug.
Projects
None yet
Development

Successfully merging a pull request may close this issue.