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 #48032 and fixes #35061
This commit is contained in:
parent
4d2d3fc5da
commit
16350526d8
2 changed files with 65 additions and 9 deletions
|
@ -897,16 +897,33 @@ fn link_args(cmd: &mut Linker,
|
|||
|
||||
let used_link_args = &trans.crate_info.link_args;
|
||||
|
||||
if crate_type == config::CrateTypeExecutable &&
|
||||
t.options.position_independent_executables {
|
||||
let empty_vec = Vec::new();
|
||||
let args = sess.opts.cg.link_args.as_ref().unwrap_or(&empty_vec);
|
||||
let more_args = &sess.opts.cg.link_arg;
|
||||
let mut args = args.iter().chain(more_args.iter()).chain(used_link_args.iter());
|
||||
if crate_type == config::CrateTypeExecutable {
|
||||
let mut position_independent_executable = false;
|
||||
|
||||
if get_reloc_model(sess) == llvm::RelocMode::PIC
|
||||
&& !sess.crt_static() && !args.any(|x| *x == "-static") {
|
||||
cmd.position_independent_executable();
|
||||
if t.options.position_independent_executables {
|
||||
let empty_vec = Vec::new();
|
||||
let args = sess.opts.cg.link_args.as_ref().unwrap_or(&empty_vec);
|
||||
let more_args = &sess.opts.cg.link_arg;
|
||||
let mut args = args.iter().chain(more_args.iter()).chain(used_link_args.iter());
|
||||
|
||||
if get_reloc_model(sess) == llvm::RelocMode::PIC
|
||||
&& !sess.crt_static() && !args.any(|x| *x == "-static") {
|
||||
position_independent_executable = true;
|
||||
}
|
||||
}
|
||||
|
||||
// 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();
|
||||
}
|
||||
} else {
|
||||
if position_independent_executable {
|
||||
cmd.position_independent_executable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1421,3 +1438,32 @@ 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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -105,6 +105,7 @@ pub trait Linker {
|
|||
fn add_object(&mut self, path: &Path);
|
||||
fn gc_sections(&mut self, keep_metadata: bool);
|
||||
fn position_independent_executable(&mut self);
|
||||
fn no_position_independent_executable(&mut self);
|
||||
fn partial_relro(&mut self);
|
||||
fn full_relro(&mut self);
|
||||
fn optimize(&mut self);
|
||||
|
@ -179,6 +180,7 @@ impl<'a> Linker for GccLinker<'a> {
|
|||
fn output_filename(&mut self, path: &Path) { self.cmd.arg("-o").arg(path); }
|
||||
fn add_object(&mut self, path: &Path) { self.cmd.arg(path); }
|
||||
fn position_independent_executable(&mut self) { self.cmd.arg("-pie"); }
|
||||
fn no_position_independent_executable(&mut self) { self.cmd.arg("-no-pie"); }
|
||||
fn partial_relro(&mut self) { self.linker_arg("-z,relro"); }
|
||||
fn full_relro(&mut self) { self.linker_arg("-z,relro,-z,now"); }
|
||||
fn build_static_executable(&mut self) { self.cmd.arg("-static"); }
|
||||
|
@ -439,6 +441,10 @@ impl<'a> Linker for MsvcLinker<'a> {
|
|||
// noop
|
||||
}
|
||||
|
||||
fn no_position_independent_executable(&mut self) {
|
||||
// noop
|
||||
}
|
||||
|
||||
fn partial_relro(&mut self) {
|
||||
// noop
|
||||
}
|
||||
|
@ -647,6 +653,10 @@ impl<'a> Linker for EmLinker<'a> {
|
|||
// noop
|
||||
}
|
||||
|
||||
fn no_position_independent_executable(&mut self) {
|
||||
// noop
|
||||
}
|
||||
|
||||
fn partial_relro(&mut self) {
|
||||
// noop
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue