diff options
| author | Jimmy Brush <code@jimmah.com> | 2018-02-10 13:16:59 -0500 |
|---|---|---|
| committer | Jimmy Brush <code@jimmah.com> | 2018-02-13 22:10:26 -0500 |
| commit | 8a72f589e5f8d628a5dcfcedbdd8eec117fbe2a2 (patch) | |
| tree | 747884289dd4b8bd2713eaa562e77976f972b003 /src | |
| parent | 16350526d8d8b514327c62b904d26f74937a1b23 (diff) | |
| download | rust-8a72f589e5f8d628a5dcfcedbdd8eec117fbe2a2.tar.gz rust-8a72f589e5f8d628a5dcfcedbdd8eec117fbe2a2.zip | |
pass correct pie args to gcc linker 2
Recent versions of gcc default to creating a position independent executable and must be explicitly told not to with the -no-pie argument. Old versions of gcc don't understand -no-pie and will throw an error. Check for that case and retry without -no-pie. This is safe because these old versions of gcc should never default to creating a position independent executable.
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc_trans/back/link.rs | 66 |
1 files changed, 23 insertions, 43 deletions
diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index a84ac5cb8bc..d15450212ae 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -652,9 +652,6 @@ fn link_natively(sess: &Session, prog = time(sess.time_passes(), "running linker", || { exec_linker(sess, &mut cmd, tmpdir) }); - if !retry_on_segfault || i > 3 { - break - } let output = match prog { Ok(ref output) => output, Err(_) => break, @@ -665,6 +662,26 @@ fn link_natively(sess: &Session, let mut out = output.stderr.clone(); out.extend(&output.stdout); let out = String::from_utf8_lossy(&out); + + // Check to see if the link failed with "unrecognized command line option: + // '-no-pie'". If so, reperform the link step without the -no-pie option. This + // is safe because if the linker doesn't support -no-pie then it should not + // default to linking executables as pie. Different versions of gcc seem to + // use different quotes in the error message so don't check for them. + if out.contains("unrecognized command line option") && out.contains("-no-pie") { + info!("linker output: {:?}", out); + warn!("Linker does not support -no-pie command line option. Retrying without."); + for arg in cmd.take_args() { + if arg.to_string_lossy() != "-no-pie" { + cmd.arg(arg); + } + } + info!("{:?}", &cmd); + continue; + } + if !retry_on_segfault || i > 3 { + break + } let msg_segv = "clang: error: unable to execute command: Segmentation fault: 11"; let msg_bus = "clang: error: unable to execute command: Bus error: 10"; if !(out.contains(msg_segv) || out.contains(msg_bus)) { @@ -912,18 +929,10 @@ fn link_args(cmd: &mut Linker, } } - // Check to see if gcc defaults to generating a position independent - // executable. If so, tell it when to disable pie. Otherwise, tell it - // when to enable it. We can't do both because older versions of gcc - // don't understand -no-pie and will blow up. - if is_pie_default(sess) { - if !position_independent_executable { - cmd.no_position_independent_executable(); - } + if position_independent_executable { + cmd.position_independent_executable(); } else { - if position_independent_executable { - cmd.position_independent_executable(); - } + cmd.no_position_independent_executable(); } } @@ -1438,32 +1447,3 @@ fn is_full_lto_enabled(sess: &Session) -> bool { Lto::ThinLocal => false, } } - -fn is_pie_default(sess: &Session) -> bool { - match sess.linker_flavor() { - LinkerFlavor::Gcc => { - let (_, mut cmd, envs) = get_linker(sess); - // This will set PATH on windows - cmd.envs(envs); - cmd.arg("-v"); - - info!("{:?}", &cmd); - - let output = cmd.command() - .stdout(Stdio::piped()).stderr(Stdio::piped()) - .spawn() - .unwrap() - .wait_with_output() - .unwrap(); - - let ret = String::from_utf8_lossy(&output.stderr) - .contains("--enable-default-pie"); - - info!("gcc {} compiled with --enable-default-pie", - if ret { "IS" } else { "is NOT" }); - - ret - }, - _ => false, - } -} |
